Entre su principales responsabilidades se encuentran:

  • Validar los formularios y mostrar los errores
  • Filtrado (Filter) de datos (escape / normalización de los datos recibidos)
  • Generar el HTML Markup del form y sus elementos

Todo esto convierte a Zend_Form en una herramienta realmente simple y potente que nos permitirá ahorrar tiempo al trabajar con formularios y generar un código mucho más pro.

Crear un formulario

Crear un formulario es muy fácil:

 $form = new Zend_Form;

Aunque en la práctica lo más limpio es crear una clase propia que extienda de Zend_Form

// application/forms/MyForm.php
class MyForm extends Zend_Form {
/* método usado para inicializar el form */
public function init() {
}
}
// en el controlador
$form = new MyForm;

Setear atributos

Lo más básico es setear el nombre, action, class, etc., lo cual como veremos es muy fácil:

 public function init() {
$this->setName('frmPrueba')
->;setAction('/process_form.php')
->setEnctype('multipart/form-data')
->setMethod('post')
->setAttrib('class', 'frmClass'); // cualquier atributo
html se puede setear con setAttrib()
}

Agregando elementos

Zend trae por default los siguientes tipos de elementos:

Button, Checkbox / multiCheckbox, Hidden, Image, Password, Radio, Reset, Select / multi-select, Submit, Text, Textarea.

Hay dos formas de agregar elementos:

 // instanciar el elemento y pasárselo al form
$form->addElement(new Zend_Form_Element_Text('username'));
// pasar el tipo del elemento al form y que este lo instancie
$form->addElement('text', 'username');

En este artículo usaremos la segunda forma cuya sintaxis es:

$form->addElement($elementType, $elementName, array $config);

Como no hay nada mejor que un ejemplo para entender las cosas:

// application/form/Registro.php
class Form_Registro extends Zend_Form {
public function init() {
$this->addElement(
'text',
'nombre',
array('required' => true, 'label' => 'Nombre')
);
$this->addElement(
'radio',
'sexo',
array(
'required' => true,
'label' => 'Sexo',
'multiOptions' => array('h' => 'Hombre', 'm' => 'Mujer')
)
);
$this->addElement(
'select',
'como_conociste',
array(
'required' => true,
'label' => 'Como nos conociste?',
'multiOptions' => array('1' => 'Por buscadores', '2'
=> 'Recomendacion')
)
);
$this->addElement('submit', 'enviar', array('label' => 'Enviar'));
}
}

Validando el formulario

Como podrás imaginar, al marcar un campo como ‘required’ lo que hacemos es marcarlo como obligatorio. Controlamos que el formulario haya sido llenado correctamente llamando al método isValid(), en este momento se controla que todos lo campos obligatorios estén completos, además de otras reglas de validación más avanzadas que se pueden crear fácilmente agregando validators a los distintos elementos (validar email, fecha, solo letras, solo números, etc., lo cual luego veremos un poco más en detalle). Si el formulario esta incompleto, automáticamente se agregan lo mensajes de error al markup del form.

// en el controlador
if ($this->getRequest()->isPost()) {
if ($form->isValid($this->getRequest()->getPost()) {
/*

El formulario esta ok (todos los campos obligatorios fueron completados y los validators no arrojaron ningún error), si isValid() devuelve false, se cargan los mensajes de error a los elementos que no estén completados correctamente:

*/
$values = $form->getValues();
$nombre = $form->nombre->getValue();
$sexo = $form->getElement('sexo')->getValue();
}
}

Como vemos en el ejemplo, podemos obtener los valores del formulario con getValues(), y obtener el valor de un elemento en particular con getValue(). Podemos acceder al elemento por sobrecarga (magic method __get) o con getElement().

Filters y Validators

Como dijimos más arriba, los filters se encargan de escapar / normalizar los datos recibidos, por ejemplo eliminar todos los números de una cadena de texto, convertir los caracteres extraños a su entidad HTML correspondiente, etc. Se pueden agregar todos los filtros que se desee.

Hay varias formas de agregar un filter a un elemento:

// instanciar el filtro y pasarselo al elemento
$element->addFilter(new Zend_Filter_Alnum());
// pasarle el nombre completo
$element->addFilter('Zend_Filter_Alnum');
// pasarle el nombre corto
$element->addFilter('Alnum');
// al momento de crear el elemento
$form->addElement('text', 'nombre', array('filters' =>
array('Alnum')));

Las últimas formas son más eficientes, ya que Zend no crea inmediatamente la instancia del filtro sino sólo cuando lo vaya a usar (lazy loading), por lo que nos ahorramos generar el objeto innecesariamente con el ahorro de memoria que esto significa, que sea mucho o poco, hace de esta una buena práctica.

Los filtros se aplicarán al momento de hacer el isValid() y cabe aclarar que Zend no modificará la fuente de datos (en este caso $_POST), sino que obtendremos los datos filtrados al pedir los valores con getValues() / getValue(). El tema de los validators es prácticamente igual:

$element->addValidator('Alnum');
$element->addValidator('StringLength', false, array(6, 20));
// al momento de crear el elemento
$form->addElement(
'text',
'nombre',
array(
'validators' => array(
'Alnum',
array('StringLength', false, array(6, 20))
)
)
);

Podemos agregar todos los validators que deseemos, al momento de validar el form se controla que cada validator este ok, si alguno falla entonces falla la validación completa y se muestran los mensajes de error. addValidator() acepta tres parámetros: el primero es el nombre del validator, el segundo es un bool que determina que, si falla este validator, no siga con los demás (true) o que siga (false), y por último un array con los valores que recibe el constructor. En nuestro ejemplo, StringLength recibe la cantidad de letras que se aceptan (entre 6 y 20).

Modificando el HTML Markup

Este primer acercamiento a Zend_Form termina aquí y te dejo el archivo que contiene el código completo para que lo descargues y pruebes.

Por último nos quedaría hablar un poco sobre como modificar el HTML generado por Zend_Form, cómo hacemos si queremos mostrar los elementos dentro de una tabla, ¿en un div? ¿mostrar un elemento al lado del otro? ¿en dos columnas? Todo esto es posible modificando los Decorators de cada elemento y del form, pero este es posiblemente uno de los temas más avanzados de Zend_Form así que requerirá un artículo propio.

Continuando con la guía:

Hasta el momento llevamos 5 capítulos de la serie, te invitamos a revisarlos si aún no lo has hecho:

Si te ha gustado la Guía Zend no olvides retwittear para que los amantes de Zend nos ayuden a seguir complementando el contenido.

Ir al siguiente capítulo: sobre decorators en Zend_Form