Nuestro blog

— por Asier Marqués

Los desarrolladores familiarizados con symfony conocen la clase sfWidgetFormChoice que nos permite crear un campo html seleccionable (tipo select, radio, checkbox y list) de una forma muy cómoda:

class ComprarForm extends sfForm{

  private $opciones = false;

  //configuramos el widget con sus opciones en la clase formulario
  public function configure()
  {

     $this->opciones  = array('manzanas',
                              'peras',
                              'limones');

     $this->setWidgets(array(
                              'quiero'   => new sfWidgetFormChoice(
                                              array('expanded' => true,
                                                    'choices'  => $this->opciones)),
                       ));

     $this->setValidators( array( 'quiero' => new sfValidatorChoice(
                                              array( 'required' => true,
                                                     'choices'=> array_keys($this->opciones)
                                                   )),
                         ));
  }

}

//en la acción creamos el formulario
  $this->formulario = new ComprarForm();

//y en la vista generamos el campo tipo <select> con las opciones configuradas
  $formulario['quiero']->render();

Hoy me he encontrado con la necesidad de tener que crear diferentes opciones segun la petición que llegue a la acción que muestra el formulario. Quizá me interese que en lugar de que mi select se rellene con frutas como en el ejemplo anterior, se rellene con todo tipo de utensilios para matar zombies, por ejemplo.

Para conseguir esto podríamos crear otra clase de formulario que contenga un widget con esas opciones y sus respectivos validadores, pero eso rompería totalmente la regla de oro en el desarrollo web ágil: “Don’t repeat yourself“.

La solución más elegante es sobreescribir el constructor de nuestra clase ComprarForm, de tal forma que se especialice con respecto al de su padre sfForm para admitir un parámetro extra llamado “tipoDeProducto”.

class ComprarForm extends sfForm{

  private $opciones = false;

  public function __construct($tipoDeProducto='frutas',
                              $defaults = array(),
                              $options = array(),
                              $CSRFSecret = null){

      switch($tipoDeProducto){
        case 'frutas':
          $this->opciones  = array('manzanas',
                                   'peras',
                                   'limones');
        break;
        case 'armas':
          $this->opciones  = array('sierra eléctrica',
                                   'recortada',
                                   'katana',
                                   'rifle de francotirador');
        break;
      }

      parent::__construct($defaults, $options, $CSRFSecret);

 }

 //configuramos el widget con sus opciones en la clase formulario
 public function configure()
 {

     $this->setWidgets(array(
                              'quiero'   => new sfWidgetFormChoice(
                                                   array('expanded' => true,
                                                         'choices'  => $this->opciones)),
                      ));

    $this->setValidators(array(
                              'quiero' => new sfValidatorChoice(
                                               array('required' => true,
                                                     'choices'=> array_keys($this->opciones)
                                                    )),
                         ));
 }

}

Ahora ya tenemos todo preparado para poder especificar desde la acción qué opciones queremos en el campo select del formulario ComprarForm

   $this->formulario = new ComprarForm('armas');

Y en la vista sin modificar el código ya nos aparecerán los productos que estamos deseando comprar.

— Posted by Asier Marqués | Posted in Desarrollo web | Posted on December 30, 2009

1 Comentario
dejar un comentario »

» RSS para los comentarios de éste post.
» TrackBack URL

Deja un comentario