944 063 154

Blog

Symfony, diferentes choices para un sfWidgetFormChoice en un mismo formulario

Publicado enDesarrollo web

Los desarrolladores familiarizados con Symfony seguro que conocerán la clase sfWidgetFormChoiceLa que nos permite crear un campo html seleccionable de una forma muy cómoda. Entre las diferentes opciones que nos proporciona esta clase se encuentran las clases tipo select, radio, checkbox y list.

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();

Otra clase de formulario con sfWidgetFormChoice

Hoy me he encontrado con la necesidad de tener que crear diferentes opciones; según 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; y así admita 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');
       &nbsp;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.