29-04-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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 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)); } } <strong>Código del controller/action:</strong> $form = new DatosForm();</code> /* 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; <strong> Código de la vista:</strong> <? 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. 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.
2. cel | octubre 20th, 2008 at 5:09 pm
Una pereguta, a que archibo ba y come se llama el archibo de
$decorators = array();…
y de
class Zend_View_Helper_Sic_decorateForm
Y como se encadena todo?
Se pude hacer esto con tu sitema?
http://zend.c.mialias.net/admin/cadmin/form
3. cel | octubre 20th, 2008 at 5:13 pm
me sale este arro
No entry is registered for key ‘DECORATORS’
4. cel | octubre 20th, 2008 at 6:05 pm
lo del Helper ya lo tengo me faltan los arrays $decorators = array();, como hago para que los pilla ‘label_noerrors’
5. William | octubre 22nd, 2008 at 5:16 pm
Pueden publicar un el codigo de un ejemplo completo, para que personas novatas (hasta ahora estoy aprendiendo ZF) podamos entender mejor.
Seria muy importante su aporte. Gracias.