944 063 154

Blog

Symfony, diferentes choices para un sfWidgetFormChoice en un mismo formulario

Publicado enDesarrollo y Programación

Los desarrolladores familiarizados con Symfony seguro que conocerán la clase sfWidgetFormChoice. Este widget se encarga de estandarizar y agrupar todas las variantes en un mismo lugar. Así, una misma selección puede mostrar diferentes formas, y también permite definitir una representación propia para la elección. La peculiaridad de sfWidgetFormChoice es que delega la responsabilidad de sus contenidos a otros widgets; pero, además, 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 nos hemos encontrado con la necesidad de tener que crear diferentes opciones; según la petición que llegue a la acción que se muestra en el formulario. Quizá nos interese que en lugar de que la select se rellene con frutas como en el ejemplo anterior; se rellene con todo tipo de utensilios que nos permitan 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“. Así que, para evitar ensuciar el código, 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-gt;opciones = array('manzanas',
                                   'peras',
                                   'limones');
       &amp;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.