Los formularios de Symfony 1.4

1.3. Configurando los widgets

1.3.1. Opciones de los widgets

Si el sitio web que muestra el formulario de contacto dispone de varios responsables, puede ser interesante añadir una lista desplegable con diferentes temas de contacto para redirigir cada mensaje al responsable adecuado (ver figura 1-7). El listado 1-9 añade un nuevo campo llamado asunto mediante una lista desplegable creada con un widget de tipo sfWidgetFormSelect.

Añadiendo un campo asunto en el formulario

Figura 1.7 Añadiendo un campo asunto en el formulario

Listado 1-9 - Añadiendo un campo asunto en el formulario

class ContactoForm extends sfForm
{
  protected static $asuntos = array('Asunto A', 'Asunto B', 'Asunto C');

  public function configure()
  {
    $this->setWidgets(array(
      'nombre'  => new sfWidgetFormInput(),
      'email'   => new sfWidgetFormInput(),
      'asunto'  => new sfWidgetFormSelect(array('choices' => self::$asuntos)),
      'mensaje' => new sfWidgetFormTextarea(),
    ));

    $this->widgetSchema->setNameFormat('contacto[%s]');
  }
}

El widget sfWidgetFormSelect, como todos los demás widgets, acepta como primer argumento una lista de opciones. A pesar de su nombre, las opciones pueden ser opcionales u obligatorios. El widget sfWidgetFormSelect dispone de una opción obligatoria llamada choices. A continuación se muestran las opciones disponibles para los widgets que ya hemos utilizado:

Widget Opciones obligatorias Otras opciones
sfWidgetFormInput - type: tipo de campo (por defecto, text)\ is_hidden: indica si el campo es oculto (por defecto, false)
sfWidgetFormSelect choices: opciones de la lista desplegable multiple: la lista permite selecciones múltiples (por defecto, false)
sfWidgetFormTextarea - -

Nota Si quieres conocer todas las opciones de un widget, puedes consultar la documentación de la API disponible online en http://www.symfony-project.org/api/1_2/. En la API se explican todas las opciones y todos sus valores por defecto. Para consultar por ejemplo las opciones del widget sfWidgetFormSelect debes acceder a http://www.symfony-project.org/api/1_2/sfWidgetFormSelect

1.3.2. Los atributos HTML de los widgets

Los widgets también aceptan como segundo argumento una lista de atributos HTML. De esta forma, esta opción permite personalizar las etiquetas HTML generadas para el formulario. El listado 1-10 muestra como añadir un atributo class al campo email.

Listado 1-10 - Definiendo atributos HTML para un widget

$widgetEmail = new sfWidgetFormInput(array(), array('class' => 'email'));

// Código HTML generado
<input type="text" name="contacto[email]" class="email" id="contacto_email" />

Los atributos HTML también permiten redefinir los identificadores generados automáticamente, como se muestra en el listado 1-11.

Listado 1-11 - Redefiniendo el atributo id

$widgetEmail = new sfWidgetFormInput(array(), array('class' => 'email', 'id' => 'email'));

// Código HTML generado
<input type="text" name="contacto[email]" class="email" id="email" />

También es posible establecer el valor que muestran por defecto los campos utilizando el atributo value como se muestra en el listado 1-12.

Listado 1-12 - Establecer valores por defecto de los widgets utilizando atributos HTML

$widgetEmail = new sfWidgetFormInput(array(), array('value' => 'Escribe tu email'));

// Código HTML generado
<input type="text" name="contacto[email]" value="Escribe tu email" id="contacto_email" />

Esta opción funciona bien para los widgets de tipo input, pero es difícil de aplicar en los widgets de tipo checkbox o radio e incluso es imposible para uno de tipo textarea. La clase sfForm incluye métodos específicos para definir los valores por defecto de cada campo de una forma uniforme para cualquier tipo de widget.

Nota Una buena práctica consiste en definir los atributos de HTML dentro de la plantilla y no en el formulario (donde también es posible hacerlo), para mantener la separación de las capas tal y como se verá en el capítulo 3.

1.3.3. Definir los valores por defecto de los campos

En ocasiones es conveniente definir un valor por defecto para cada campo. El ejemplo típico es el mensaje de ayuda que se muestra en cada campo del formulario y que se oculta cuando el usuario se situa en ese campo. El listado 1-13 muestra cómo definir los valores por defecto a través de los métodos setDefault() y setDefaults().

Listado 1-13 - Establecer los valores por defecto en los widgets mediante los métodos setDefault() y setDefaults()

class ContactoForm extends sfForm
{
  public function configure()
  {
    // ...

    $this->setDefault('email', 'Escribe tu email');

    $this->setDefaults(array('email' => 'Escribe tu email', 'nombre' => 'Escribe tu nombre'));
  }
}

Los métodos setDefault() y setDefaults() son muy útiles para definir los mismos valores por defecto para cada instancia del mismo formulario. Si se quiere modificar un objeto existente utilizando un formulario, los valores por defecto dependen de la instancia y por tanto, deben ser dinámicos. El listado 1-14 muestra cómo el constructor de la clase sfForm dispone de un primer argumento que establece dinámicamente los valores por defecto.

Listado 1-14 - Establecer los valores por defecto de los widgets mediante el constructor de sfForm

public function executeIndex($peticion)
{
  $this->formulario = new ContactoForm(array('email' => 'Escribe tu email', 'nombre' => 'Escribe tu nombre'));

  // ...
}