Los formularios de Symfony 1.4

12.4. Widgets para elecciones

12.4.1. Tipos de elecciones

Cuando el usuario debe elegir un valor entre una lista de posibilidades, HTML ofrece diferentes formas de representar esa elección:

  • Una etiqueta <select>:
Lista desplegable simple

Figura 12.1 Lista desplegable simple

  • Una etiqueta <select> con el atributo multiple:
Lista desplegable que permite seleccionar varias opciones

Figura 12.2 Lista desplegable que permite seleccionar varias opciones

  • Una lista de etiquetas <input> con el atributo type igual a radio:
Grupo de radio buttons

Figura 12.3 Grupo de radio buttons

  • Una lista de etiquetas <input> con el atributo type igual a checkbox:
Grupo de checkboxes

Figura 12.4 Grupo de checkboxes

A pesar de sus diferencias, todas ellas permiten al usuario seleccionar una o varias opciones entre una lista finita de posibilidades.

El widget sfWidgetFormChoice estandariza y agrupa todas estas variantes en un único widget. De esta forma, la misma elección se puede mostrar de cualquiera de las cuatro formas mostradas anteriormente. Como se verá más adelante, también es posible definir una representación propia para la elección.

sfWidgetFormChoice es un widget especial porque delega la responsabilidad de mostrar sus contenidos a otro widget. La representación visual del widget se controla mediante las opciones expanded y multiple:

Valor de expanded Valor de multiple Widget utilizado
true true sfWidgetFormSelectCheckbox
true false sfWidgetFormSelectRadio
false true sfWidgetFormSelectMany
false false sfWidgetFormSelect

Nota Los widgets sfWidgetFormSelect, sfWidgetFormSelectMany, sfWidgetFormSelectCheckbox y sfWidgetFormSelectRadio que utiliza el widget sfWidgetFormChoice para mostrarse son widgets normales que también se pueden utilizar de forma individual. En esta sección no se documenta el uso de cada uno de estos widgets porque casi siempre es mejor utilizar el widget sfWidgetFormChoice, que es mucho más flexible.

A continuación se muestra la representación HTML de cada widget:

$w = new sfWidgetFormChoice(array(
  'choices' => array('Fabien Potencier', 'Fabian Lange'),
));
Lista desplegable simple

Figura 12.5 Lista desplegable simple

$w = new sfWidgetFormChoice(array(
  'multiple' => true,
  'choices'  => array('PHP', 'symfony', 'Doctrine', 'Propel', 'model'),
));
Lista desplegable que permite seleccionar varias opciones

Figura 12.6 Lista desplegable que permite seleccionar varias opciones

$w = new sfWidgetFormChoice(array(
  'expanded' => true,
  'choices'  => array('published', 'draft', 'deleted'),
));
Grupo de radio buttons

Figura 12.7 Grupo de radio buttons

$w = new sfWidgetFormChoice(array(
  'expanded' => true,
  'multiple' => true,
  'choices'  => array('A week of symfony', 'Call the expert', 'Community'),
));
Grupo de checkboxes

Figura 12.8 Grupo de checkboxes

12.4.2. Agrupación de opciones

El widget sfWidgetFormChoice también soporta la agrupación de opciones cuando se pasa un array de arrays como valor de la opción choices:

$choices = array(
  'Europe'  => array('France' => 'France', 'Spain' => 'Spain', 'Italy' => 'Italy'),
  'America' => array('USA' => 'USA', 'Canada' => 'Canada', 'Brazil' => 'Brazil'),
);

$w = new sfWidgetFormChoice(array('choices' => $choices));
Agrupación de opciones

Figura 12.9 Agrupación de opciones

Las opciones expanded y multiple siguen funcionando como antes:

$w = new sfWidgetFormChoice(array(
  'choices'  => $choices,
  'expanded' => true,
));
Agrupación de opciones expandidas

Figura 12.10 Agrupación de opciones expandidas

La plantilla utilizada para mostrar el widget también se puede personalizar:

$w = new sfWidgetFormChoice(array(
  'choices'  => $choices,
  'expanded' => true,
  'renderer_options' => array('template' => '<strong>%group%</strong> %options%'),
));
Agrupación de opciones expandidas y con formato personalizado

Figura 12.11 Agrupación de opciones expandidas y con formato personalizado

A continuación se muestran otros ejemplos de combinaciones de opciones:

$w = new sfWidgetFormChoice(array(
  'choices'  => $choices,
  'multiple' => true,
));
Agrupación de opciones con selección múltiple

Figura 12.12 Agrupación de opciones con selección múltiple

$w = new sfWidgetFormChoice(array(
  'choices'  => $choices,
  'multiple' => true,
  'expanded' => true,
  'renderer_options' => array('template' => '<strong>%group%</strong> %options%'),
));
Agrupación de opciones expandida y con selección múltiple

Figura 12.13 Agrupación de opciones expandida y con selección múltiple

Nota Cuando el widget se muestra con una etiqueta <select> simple, se utiliza la etiqueta <optgroup> estándar.

12.4.3. Opciones soportadas

La siguiente tabla muestra todas las opciones soportadas por el widget:

Opción Descripción
choices Array con los valores de las opciones (obligatorio)
multiple true si la etiqueta <select> permite selecciones múltiples
expanded true para mostrar el widget de forma expandida
renderer_class La clase que se utiliza en vez de la clase por defecto
renderer_options Las opciones que se pasan a la clase que muestra el widget
renderer El widget utilizado para mostrar las opciones (si se utiliza esta opción, se ignoran las opciones expanded y renderer_options)\ La opción choices será: new sfCallable($thisWidgetInstance, 'getChoices')

Los widgets sfWidgetFormSelectCheckbox y sfWidgetFormSelectRadio soportan las siguientes opciones:

Opción Descripción
label_separator El separador que se utiliza entre el <input> del checkbox/radio button y el título de la opción
class El atributo class que se utiliza en la etiqueta <ul> principal
separator El separador que se utiliza entre los <input> de cada checkbox/radio button
formatter Código que se ejecuta para mostrar las opciones del checkbox. El código recibe como argumentos el widget y el array de etiquetas <input>
template La plantilla que se utiliza al agrupar las opciones (puede hacer uso de las variables %group% y %options%)

Nota El widget sfWidgetFormChoiceMany es en realidad un atajo del widget sfWidgetFormChoice con la opción multiple establecida automáticamente a true.

12.4.4. Representación mediante una lista doble

Cuando el usuario puede seleccionar varias opciones, normalmente es mejor mostrar las opciones seleccionadas en otra lista. El widget sfWidgetFormSelectDoubleList permite mostrar la selección de opciones en forma de lista doble:

$w = new sfWidgetFormChoice(array(
  'choices'        => array('PHP', 'symfony', 'Doctrine', 'Propel', 'model'),
  'renderer_class' => 'sfWidgetFormSelectDoubleList',
));
Lista doble

Figura 12.14 Lista doble

Nota Este widget forma parte del plugin sfFormExtraPlugin.

Nota Este widget requiere el uso de JavaScript para su funcionamiento. Si quieres obtener las rutas de los archivos JavaScript, puedes emplear el método getJavaScripts() del widget:

$rutasArchivos = $w->getJavascripts();
Opción Descripción
choices Array con los valores de las opciones (obligatorio)
class El atributo class principal del widget
class_select El atributo class que se utiliza en las dos etiquetas <select>
label_unassociated El título de las opciones no seleccionadas
label_associated El título de las opciones seleccionadas
unassociate El código HTML del enlace para deseleccionar una opción
associate El código HTML del enlace para seleccionar una opción
template El código HTML de la plantilla que se utiliza para mostrar el widget. Las variables disponibles en la plantilla son: %label_associated%, %label_unassociated%, %associate%, %unassociate%, %associated%, %unassociated%, %class%

12.4.5. Autocompletado

Cuando el usuario debe seleccionar un valor entre un gran número de opciones, crear una lista enorme con todas las opciones no es práctico. El widget sfWidgetFormJQueryAutocompleter soluciona este problema convirtiendo una etiqueta <input> simple en un elemento que autocompleta el texto escrito por el usuario.

Nota Este widget es parte del plugin sfFormExtraPlugin. Como los archivos de las librerías JQuery y JQuery UI no se incluyen en sfFormExtraPlugin, debes instalarlos e incluirlos a mano.

$w = new sfWidgetFormChoice(array(
  'choices'          => array(),
  'renderer_class'   => 'sfWidgetFormJQueryAutocompleter',
  'renderer_options' => array('url' => '/script_autocompletado'),
));

Nota Este widget requiere el uso de algunas hojas de estilos y archivos JavaScript para su funcionamiento. Los métodos getJavaScripts() y getStylesheets() permiten obtener las rutas de todos estos archivos.

La opción url es la URL a la que accede el widget para obtener la lista de sugerencias a partir del texto introducido por el usuario. Esta URL incluye dos parámetros:

  • q: la cadena de texto escrita por el usuario
  • limit: el máximo número de sugerencias que debe devolver el script

La respuesta del script debe ser una representación JSON válida del array de opciones (puedes utilizar la función json_encode() de PHP para convertir un array al formato JSON).

Opción Descripción
url La URL a la que se accede para obtener las opciones (obligatorio)
config Array de JavaScript que configura el widget de autocompletado de JQuery
value_callback Código que se ejecuta sobre cada valor antes de mostrarlo

Si la lista de sugerencias está relacionada con un modelo de Propel, es decir, con una tabla de la base de datos, puedes utilizar el widget sfWidgetFormPropelJQueryAutocompleter, que está optimizado para búsquedas a partir de la clave primaria:

$w = new sfWidgetFormChoice(array(
  'renderer_class'   => 'sfWidgetFormPropelJQueryAutocompleter',
  'renderer_options' => array(
    'model' => 'Articulo',
    'url'   => '/script_autocompletado',
  ),
));
Opción Descripción
model La clase del modelo (obligatoria)
method El método que se utiliza para convertir el objeto en una cadena de texto (__toString() por defecto)

12.4.6. Elecciones asociadas con modelos de Propel

Si las opciones están relacionadas con un modelo de Propel (por ejemplo cuando el usuario puede cambiar una clave externa) puedes utilizar el widget sfWidgetFormPropelChoice:

$w = new sfWidgetFormPropelChoice(array(
  'model'     => 'Articulo',
  'add_empty' => false,
));

El widget obtiene automáticamente las opciones (choices) a partir de la clase del modelo (model). Este widget se puede configurar mediante las siguientes opciones:

Opción Descripción
model La clase del modelo Propel (obligatoria)
add_empty Indica si se debe mostrar un primer elemento vacío en la lista (false por defecto) Si el valor no es de tipo booleano, se utiliza como texto de la opción
method El método utilizado para mostrar el valor de los objetos (__toString por defecto)
key_method El método utilizado para mostrar la clave de los objetos (getPrimaryKey por defecto)
order_by Array compuesto por dos opciones: 1) La columna por la que se ordenan los resultados (debe indicarse con el formato PhpName) 2) Criterio de ordenación (asc o desc)
criteria Objeto Criteria que se utiliza para obtener los objetos
connection El nombre de la conexión Propel que se utiliza (null por defecto)
multiple true si la etiqueta <select> permite selecciones múltiples
peer_method El método peer utilizado para obtener los objetos

12.4.7. Elecciones asociadas con modelos de Doctrine

Si las opciones están relacionadas con un modelo de Doctrine (por ejemplo cuando el usuario puede cambiar una clave externa) puedes utilizar el widget sfWidgetFormDoctrineChoice:

$w = new sfWidgetFormDoctrineChoice(array(
  'model'     => 'Articulo',
  'add_empty' => false,
));

El widget obtiene automáticamente las opciones (choices) a partir de la clase del modelo (model). Este widget se puede configurar mediante las siguientes opciones:

Opción Descripción
model La clase del modelo (obligatoria)
add_empty Indica si se debe mostrar un primer elemento vacío en la lista (false por defecto) Si el valor no es de tipo booleano, se utiliza como texto de la opción
method El método utilizado para mostrar el valor de los objetos (__toString por defecto)
key_method El método utilizado para mostrar la clave de los objetos (getPrimaryKey por defecto)
order_by Array compuesto por dos opciones: 1) La columna por la que se ordenan los resultados (debe indicarse con el formato PhpName) 2) Criterio de ordenación (asc o desc)
query Consulta que se utiliza para obtener los objetos
connection El nombre de la conexión Doctrine que se utiliza (null por defecto)
multiple true si la etiqueta <select> permite selecciones múltiples
table_method El método utilizado para obtener los objetos