Zend_Form: donde generar el HTML

Abril 29th, 2008 Luis Artola

Uno de los mayores dilemas a la hora de usar el Zend_Form es gestionar la generación de HTML en la propia clase de Zend_Form. Como principio general dentro del MVC, el HTML debería generarse dentro de la vista. Nunca en un controller y menos en un Model (aunque sea un model de formulario y no de acceso a datos, eso da igual).

Mi solución es decidir qué decorators se aplicarán al formulario en la propia vista, mediante el uso de un helper. Veámoslo.

Código del formulario:

class DatosForm extends Zend_Form
{
public function __construct($options = null)
{
parent::__construct($options);
$this->setName('Datos de facturación');
$this->setAttrib('id', 'datosfac');


$Nombre = new Zend_Form_Element_Text('Nombre');
$Nombre->setLabel('Nombre')
->setRequired(true)
->addValidator('NotEmpty');
$submit = new Zend_Form_Element_Submit('submit');
$submit->setLabel('Actualizar');
$this->addElements(array($Nombre, $submit));
}
}

Código del controller/action:


$form = new DatosForm();


/*
Aquí iría una gestión de validación del formulario, get, post, bla bla bla que no interesa para éste ejemplo
*/
$this->view->form = $form;

Código de la vista:

<? echo $this->sic_decorateForm($this->form,'label_noerrors');?>

Como puede verse, hasta aquí el Zend_Form sólo se encarga de definir qué campos, de qué tipos y con qué validaciones. El controlador sólo se encarga de gestionar el flujo de envío del formulario y la vista de mostrarlo. Cada uno tiene sus responsabilidades perfectamente definidas.

Clave está en el decorador “sic_decorateForm” al que se le pasan dos parámetros. El primero, el propio formulario, y el segundo una configuración de decorators llamada “label_noerrors” (que en éste caso significa que se decorará con labels, y que no se sacarán los errores).

El código del helper sería:

class Zend_View_Helper_Sic_decorateForm
{
public function sic_decorateForm(Zend_Form $form,$config)
{
$form->clearDecorators();
$form->setAttrib('class',$config);
$decorators = Zend_Registry::get('DECORATORS');
$decorators = $decorators[$config];
$form->addDecorators($decorators['form']);
$form->setElementDecorators($decorators['elements']);
return $form;
}
}

Como puede verse es el helper, llamado desde la vista, el que aplica los decorators al form. Y los decorators que se aplican los hemos decidido en la propia vista (¡bien!) . Además, se asigna la clase $config (en éste caso “label_noerrors”) al formulario. Lo que nos permitirá crear una clase de css con el mismo nombre que la configuración de decorators para controlar la apariencia del formulario no sólo a nivel de html, sino también a nivel de css.

Por último, ¿de dónde salen las configuraciones de decorators? Yo las he puesto en un fichero a parte, que cargo durante el bootstraping. Sería el siguiente:


$decorators = array();
$decorators['lista_ul']['elements'] = array(
array('ViewHelper'),
array('Description'),
array('Errors'),
array('Label', array('tag' => null, 'separator'=>' ')),
array('HtmlTag', array('tag' => 'li', 'class'=>'element-group')),
);
$decorators['lista_ul']['form'] = array(
array('FormElements'),
array('HtmlTag', array('tag' => '<ul>')),
array('Form'));
$decorators['label_noerrors']['elements'] = array(
array('ViewHelper'),
array('Label', array('tag' => null, 'separator'=>' '))
);
$decorators['label_noerrors']['form'] = array(
array('FormElements'),
array('HtmlTag', array('tag' => null)),
array('Form'));

Como puede verse existen dos configuraciones de decorators: label_noerrors y lista_ul. Hacerlo de ésta manera tiene otra ventaja: si quisiéramos cambiar la apariencia html del formulario sólo tendríamos que cambiar el parámetro $config con el que llamados al helper. Además, si a lo largo de nuestra aplicación tenemos varios formularios con la apariencia label_noerrors y queremos cambiar esa apariencia, con cambiar la definición de esa decoración cambiará en todos los formularios que la usan a la vez.

¿Qué os parece ésta solución? Yo por ahora no le he encontrado ninguna desventaja. ¿le veis alguna?

1 Comment Nuevo comentario

  • 1. Pablo  |  Abril 29th, 2008 at 12:46 pm

    No estaba usando Zend_Form porque me parecia una locura hacerlo desde el modelo o el controller como vi en varios ejemplos. Esta es una excelente forma de usarlo.

Comenta el articulo:

Requerido

Requerido,