1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- EN-Revision: 20115 -->
4 <sect1 id="zend.form.elements">
5 <title>Creando elementos de formulario usando Zend_Form_Element</title>
7 <para> Un formulario esta compuesto de elementos, que normalmente
8 corresponden al elemento HTML input.
9 <classname>Zend_Form_Element</classname> encapsula elementos de
10 formulario individualmente, con las siguientes áreas de responsabilidad: </para>
14 <para>validación (¿los datos enviados son válidos?)</para>
18 <para>captura de códigos y mensajes de error</para>
24 <para>filtrado (¿cómo es escapado y normalizado el elemento para su
25 validación y/o salida?</para>
29 <para>generación (¿cómo es mostrado el elemento?)</para>
33 <para>metadatos y atributos (¿qué información amplía la definición
38 <para> La clase base, <classname>Zend_Form_Element</classname> , funciona
39 por defecto para varios casos, pero es mejor extender la clase para
40 elementos con fines especiales de uso común. Adicionalmente, Zend
41 Framework contiene un número de elementos <acronym>XHTML</acronym>
42 estándar; puede leer de ellos <link linkend="zend.form.standardElements"
43 >en el capítulo Elementos Estándares</link>
46 <sect2 id="zend.form.elements.loaders">
47 <title>Cargadores de Plugin</title>
50 <classname>Zend_Form_Element</classname> hace uso de <link
51 linkend="zend.loader.pluginloader"
52 >Zend_Loader_PluginLoader</link> para permitir a los
53 desarrolladores especificar ubicaciones de validadores, filtros y
54 decoradores alternos. Cada uno tiene su propio cargador de plugin
55 asociado a él y métodos de acceso generales usados para su
56 recuperación y modificación. </para>
58 <para>Los siguientes tipos de cargadores son usados con los varios
59 métodos del cargador de plugin: 'validate', 'filter', y 'decorator'.
60 Los nombres son sensibles a mayúsculas y minúsculas.</para>
62 <para>Los métodos usados para interactuar con los cargadores de plugin
63 son los siguientes:</para>
68 <methodname>setPluginLoader($loader, $type)</methodname> :
69 <varname>$loader</varname> es el propio objeto cargador,
70 mientras <varname></varname> es uno de los tipos arriba
71 mencionados. Esto establece el cargador de plugin para el
72 tipo dado en el objeto cargador recién especificado. </para>
77 <methodname>getPluginLoader()</methodname> : obtiene el
78 cargador de plugin asociado con <varname></varname> .
84 <methodname>addPrefixPath($prefix, $path, $type =
85 null)</methodname> : agrega una asociación prefijo/ruta
86 para el cargador especificado por <varname>$type</varname> .
87 Si <varname>$type</varname> es <constant>NULL</constant>, se intentará agregar la
88 ruta a todos los cargadores, añadiendo el prefijo a cada
89 "_Validate", "_Filter" y "_Decorator"; y agregandole
90 "Validate/", "Filter/" y "Decorator/" a la ruta. Si tiene
91 todas sus clases extras para elementos de formulario dentro
92 de una jerarquía común, este método es conveniente para
93 establecer el prefijo para todas ellas. </para>
98 <methodname>addPrefixPaths(array $spec)</methodname> : le
99 permite añadir varias rutas de una sola vez a uno o más
100 cargadores de plugin. Se espera cada elemento de la matriz
101 sea un array con claves 'path', 'prefix', y 'type'. </para>
105 <para>Validadores, filtros y decoradores personalizados son una manera
106 simple de compartir funcionalidad entre formularios y encapsular
107 funcionalidad personalizada.</para>
109 <example id="zend.form.elements.loaders.customLabel">
110 <title>Etiqueta personalizada</title>
112 <para>Un uso común de los plugins es proveer reemplazos para las
113 clases estándares. Por ejemplo, si desea proveer una
114 implementación diferente del decorador 'Label' -- por ejemplo,
115 para añadir siempre dos puntos -- puede crear su propio
116 decorador 'Label' con su propio prefijo de clase, y entonces
117 añadirlo a su prefijo de ruta.</para>
119 <para>Comencemos con un decorador de etiqueta personalizado. Le
120 daremos el prefijo "My_Decorator", y la clase estará en el
121 archivo "My/Decorator/Label.php".</para>
123 <programlisting language="php"><![CDATA[
124 class My_Decorator_Label extends Zend_Form_Decorator_Abstract
126 protected $_placement = 'PREPEND';
128 public function render($content)
130 if (null === ($element = $this->getElement())) {
133 if (!method_exists($element, 'getLabel')) {
137 $label = $element->getLabel() . ':';
139 if (null === ($view = $element->getView())) {
140 return $this->renderLabel($content, $label);
143 $label = $view->formLabel($element->getName(), $label);
145 return $this->renderLabel($content, $label);
148 public function renderLabel($content, $label)
150 $placement = $this->getPlacement();
151 $separator = $this->getSeparator();
153 switch ($placement) {
155 return $content . $separator . $label;
158 return $label . $separator . $content;
164 <para>Ahora diremos al elemento que use esta ruta cuando busque por
167 <programlisting language="php"><![CDATA[
168 $element->addPrefixPath('My_Decorator', 'My/Decorator/', 'decorator');
171 <para>Alternativamente, podemos hacerlo en el formulario para
172 asegurar que todos los decoradores usen esta ruta:</para>
174 <programlisting language="php"><![CDATA[
175 $form->addElementPrefixPath('My_Decorator', 'My/Decorator/', 'decorator');
178 <para>Con esta ruta añadida, cuando agregue un decorador, la ruta
179 'My/Decorator' será consultada primero en búsqueda de la
180 existencia del decorador en este lugar. Como resultado,
181 'My_Decorator_Label' ahora será utilizado cuando el decorador
182 'Label' sea requerido.</para>
186 <sect2 id="zend.form.elements.filters">
187 <title>Filters</title>
189 <para> A menudo es útil y/o necesario realizar alguna normalización en
190 la entrada antes de la validación – por ejemplo, puede querer
191 eliminar todo el <acronym>HTML</acronym> , pero realizar las
192 validaciones sobre lo restante para asegurarse que el envío es
193 válido. O puede eliminar los espacios en blanco al inicio o fin de
194 la entrada para asegurarse de que un validador StringLenth (longitud
195 de la cadena) no regrese un positivo falso. Estas operaciones pueden
196 realizarse usando <classname>Zend_Filter</classname> , y
197 <classname>Zend_Form_Element</classname> que soportan cadenas de
198 filtros, permitiéndole especificar múltiples filtros secuenciales a
199 utilizar. El filtrado sucede tanto en la validación como cuando
200 recupera el valor del elemento vía
201 <methodname>getValue()</methodname> : </para>
203 <programlisting language="php"><![CDATA[
204 $filtered = $element->getValue();
208 <para>Los filtros pueden ser agregados a la pila de dos maneras:</para>
212 <para>pasándolo en una instancia de filtro específica</para>
216 <para>proveyendo un nombre de filtro – el correspondiente nombre
217 corto o completo de la clase</para>
221 <para>Veamos algunos ejemplos:</para>
223 <programlisting language="php"><![CDATA[
224 // Instancia específica del filtro
225 $element->addFilter(new Zend_Filter_Alnum());
227 // El correspondiente nombre completo de la clase:
228 $element->addFilter('Zend_Filter_Alnum');
230 // Nombre corto del filtro:
231 $element->addFilter('Alnum');
232 $element->addFilter('alnum');
235 <para>Los nombres cortos son típicamente el nombre del filtro sin el
236 prefijo. En el caso predeterminado, esto se refiere a sin el prefijo
237 'Zend_Filter_'. Además, la primera letra no necesita estar en
241 <title>Usando clases de filtros personalizados</title>
243 <para> Si tiene su propio conjunto de clases de filtro, puede
244 informarle de ellas a <classname>Zend_Form_Element</classname>
245 usando <methodname>addPrefixPath()</methodname> . Por ejemplo,
246 si tiene filtros con el prefijo 'My_Filter', puede indicárselo a
247 <classname>Zend_Form_Element</classname> de la siguiente
250 <programlisting language="php"><![CDATA[
251 $element->addPrefixPath('My_Filter', 'My/Filter/', 'filter');
254 <para>(Recuerde que el tercer argumento indica el cargador de plugin
255 sobre el cual ha de ejecutarse la acción.)</para>
258 <para> Si en algún momento necesita un valor no filtrado, use el método
259 <methodname>getUnfilteredValue()</methodname> : </para>
261 <programlisting language="php"><![CDATA[
262 $unfiltered = $element->getUnfilteredValue();
265 <para> Para mayor información sobre filtros, vea la <link
266 linkend="zend.filter.introduction">documentación de
267 Zend_Filter</link> . </para>
269 <para>Métodos asociados con filtros incluyen:</para>
274 <methodname>addFilter($nameOfFilter, array $options =
281 <methodname>addFilters(array $filters)</methodname>
287 <methodname>setFilters(array $filters)</methodname>
288 (sobreescribe todos los filtros) </para>
293 <methodname>getFilter($name)</methodname> (recupera un
294 objeto filtro por su nombre) </para>
299 <methodname>getFilters()</methodname> (recupera todos los
305 <methodname>removeFilter($name)</methodname> (elimina un
306 filtro por su nombre) </para>
311 <methodname>clearFilters()</methodname> (elimina todos los
317 <sect2 id="zend.form.elements.validators">
318 <title>Validadores</title>
320 <para> Si sigue el mantra de seguridad "filtrar la entrada, escapar la
321 salida" querrá validar ("filtrar la entrada") los datos de los
322 formularios. En <classname>Zend_Form</classname> cada elemento
323 contiene su propia cadena de validadores, consistente en validadores
324 <methodname>Zend_Validate_*</methodname> . </para>
326 <para>Los validadores pueden ser agregados de dos maneras:</para>
330 <para>pasándolo en una instancia de validador específica </para>
334 <para>proveyendo un nombre de validador – el correspondiente
335 nombre corto o completo de clase</para>
339 <para>Veamos algunos ejemplos:</para>
341 <programlisting language="php"><![CDATA[
342 // Instancia específica del validador:
343 $element->addValidator(new Zend_Validate_Alnum());
345 // El correspondiente nombre completo de la clase:
346 $element->addValidator('Zend_Validate_Alnum');
348 // Nombre corto del validador:
349 $element->addValidator('Alnum');
350 $element->addValidator('alnum');
353 <para>Los nombres cortos son típicamente el nombre del validador sin el
354 prefijo. En el caso predeterminado, esto se refiere a sin el prefijo
355 'Zend_Validate_'. Además, la primera letra no necesita estar en
359 <title>Usando clases de validación personalizadas</title>
361 <para> Si tiene su propio conjunto de clases de validación, puede
362 informarle de ellas a <classname>Zend_Form_Element</classname>
363 usando <methodname>addPrefixPath()</methodname> . Por ejemplo,
364 si tiene validadores con el prefijo 'My_Validator', puede
365 indicárselo a <classname>Zend_Form_Element</classname> de la
366 siguiente manera: </para>
368 <programlisting language="php"><![CDATA[
369 $element->addPrefixPath('My_Validator', 'My/Validator/', 'validate');
372 <para>(Recuerde que el tercer argumento indica el cargador de plugin
373 sobre el cual ha de ejecutarse la acción.)</para>
376 <para> Si el fallo de un validador debe evitar validaciones posteriores,
377 pase el boleano <constant>TRUE</constant> como segundo parámetro: </para>
379 <programlisting language="php"><![CDATA[
380 $element->addValidator('alnum', true);
383 <para> Si está usando la cadena nombre para añadir el validador, y la
384 clase del validador acepta argumentos para su constructor, puede
385 pasarlos a el tercer parámetro de
386 <methodname>addValidator()</methodname> como un array: </para>
388 <programlisting language="php"><![CDATA[
389 $element->addValidator('StringLength', false, array(6, 20));
392 <para> Los argumentos pasados de esta manera deben estar en el orden en
393 el cual son definidos en el constructor. El ejemplo de arriba
395 <classname>Zend_Validate_StringLenth</classname> con los
396 parámetros <varname>$min</varname> y <varname>$max</varname> : </para>
398 <programlisting language="php"><![CDATA[
399 $validator = new Zend_Validate_StringLength(6, 20);
403 <title>Estipulando mensajes de error de validación
404 personalizados</title>
406 <para> Algunos desarrolladores querrán estipular mensajes de error
407 personalizados para un validador. El argumento
408 <varname>$options</varname> de
409 <methodname>Zend_Form_Element::addValidator()</methodname>
410 le permite hacerlo proporcionando la clave 'messages' y
411 estableciendolos en un array de pares clave/valor para
412 especificar las plantillas de mensaje. Necesitará conocer los
413 códigos de error de los diferentes tipos de error de un
414 validador en particular. </para>
416 <para> Una opción mejor es usar
417 <classname>Zend_Translate_Adapter</classname> con su
418 formulario. Los códigos de error son automáticamente pasados al
419 adaptador por el decorador Errors por defecto; puede especificar
420 su propias cadenas de mensaje de error mediante la creación de
421 traducciones para los varios códigos de error de sus
425 <para> Puede también establecer varios validadores a la vez, usando
426 <methodname>addValidators()</methodname> . Su uso básico es
427 pasar una matriz de arrays, donde cada array contenga de 1 a 3
428 valores, correspondientes al constructor de
429 <methodname>addValidator()</methodname> : </para>
431 <programlisting language="php"><![CDATA[
432 $element->addValidators(array(
433 array('NotEmpty', true),
435 array('stringLength', false, array(6, 20)),
439 <para>Si quiere ser más detallado o explícito, puede utilizar las claves
440 'validator', 'breakChainOnFailure', y 'options' en el array:</para>
442 <programlisting language="php"><![CDATA[
443 $element->addValidators(array(
445 'validator' => 'NotEmpty',
446 'breakChainOnFailure' => true),
447 array('validator' => 'alnum'),
449 'validator' => 'stringLength',
450 'options' => array(6, 20)),
454 <para>Este uso es bueno para ilustrar cómo puede configurar validadores
455 en un archivo de configuración:</para>
457 <programlisting language="ini"><![CDATA[
458 element.validators.notempty.validator = "NotEmpty"
459 element.validators.notempty.breakChainOnFailure = true
460 element.validators.alnum.validator = "Alnum"
461 element.validators.strlen.validator = "StringLength"
462 element.validators.strlen.options.min = 6
463 element.validators.strlen.options.max = 20
466 <para>Note que cada elemento tiene una clave, la necesite o no; esta es
467 una limitación del uso de archivos de configuración -- pero también
468 ayuda a hacer más explicito el para qué son usados los argumentos.
469 Sólo recuerde que cualesquiera opciones del validador deben ser
470 especificadas en orden.</para>
472 <para> Para validar un elemento, pase el valor a
473 <methodname>isValid()</methodname> : </para>
475 <programlisting language="php"><![CDATA[
476 if ($element->isValid($value)) {
484 <title>Validación operando en valores filtrados</title>
487 <methodname>Zend_Form_Element::isValid()</methodname> > siempre
488 filtra los valores antes de la validación a través de la cadena
489 de filtros. Vea <link linkend="zend.form.elements.filters">la
490 sección de filtros</link> para más información. </para>
494 <title>Contexto de validación</title>
497 <methodname>Zend_Form_Element::isValid()</methodname> > soporta
498 un argumento adicional, <varname>$context</varname> .
499 <methodname>Zend_Form::isValid()</methodname> pasa todo el
500 conjunto de datos procesados a <varname>$context</varname>
501 cuando valida un formulario, y
502 <methodname>Zend_Form_Element::isValid()</methodname> >, a
503 su vez, lo pasa a cada validador. Esto significa que puede
504 escribir validadores que son conscientes de los datos pasados a
505 otros elementos del formulario. Como ejemplo, considere un
506 formulario de registro estándar que tiene campos para la
507 contraseña y la confirmación de la contraseña; una validación
508 sería que los dos campos coincidan. Este validador puede tener
509 un aspecto como el siguiente: </para>
511 <programlisting language="php"><![CDATA[
512 class My_Validate_PasswordConfirmation extends Zend_Validate_Abstract
514 const NOT_MATCH = 'notMatch';
516 protected $_messageTemplates = array(
517 self::NOT_MATCH => 'Password confirmation does not match'
520 public function isValid($value, $context = null)
522 $value = (string) $value;
523 $this->_setValue($value);
525 if (is_array($context)) {
526 if (isset($context['password_confirm'])
527 && ($value == $context['password_confirm']))
531 } elseif (is_string($context) && ($value == $context)) {
535 $this->_error(self::NOT_MATCH);
542 <para> Los validadores son procesados en orden. Cada validador es
543 procesado, a menos que un validador creado con un valor true para
544 <methodname>breakChainOnFailure</methodname> falle su
545 validación. Asegúrese de especificar sus validadores en un orden
548 <para>Después de una validación fallida, puede recuperar los códigos y
549 mensajes de error de la cadena del validador:</para>
551 <programlisting language="php"><![CDATA[
552 $errors = $element->getErrors();
553 $messages = $element->getMessages();
556 <para>(Nota: los mensajes de error retornados son un array asociativo de
557 pares código / mensaje de error.)</para>
559 <para> En adición a los validadores, puede especificar que un elemento
560 es necesario, usando <methodname>setRequired(true)</methodname> .
561 Por defecto, esta bandera es <constant>FALSE</constant> , lo que
562 significa que pasará su cadena de validadores si ningún valor es
563 pasado a <methodname>isValid()</methodname> . Puede modificar este
564 comportamiento en un número de maneras: </para>
568 <para> Por defecto, cuando un elemento es requerido, una
569 bandera, 'allowEmpty', también es true. Esto quiere decir
570 que si un valor empty es evaluado pasándolo a
571 <methodname>isValid()</methodname> , los validadores
572 serán saltados. Puede intercalar esta bandera usando el
574 <methodname>setAllowEmpty($flag)</methodname> ; cuando
575 la bandera es false, si un valor es pasado, los validadores
576 seguirán ejecutándose. </para>
580 <para> Por defecto, si un elemento es requerido, pero no
581 contiene un validador 'NotEmpty',
582 <methodname>isValid()</methodname> añadirá uno en la
583 cima de la pila, con la bandera
584 <methodname>breakChainOnFailure</methodname>
585 establecido. Esto hace que la bandera requerida tenga un
586 significado semántico: si ningún valor es pasado,
587 inmediatamente invalidamos el envío y se le notifica al
588 usuario, e impedimos que otros validadores se ejecuten en lo
589 que ya sabemos son datos inválidos. </para>
591 <para> Si no quiere este comportamiento, puede desactivarlo
592 pasando un valor false a
593 <methodname>setAutoInsertNotEmptyValidator($flag)</methodname>
594 ; esto prevendrá a <methodname>isValid()</methodname> de
595 colocar un validador 'NotEmpty' en la cadena de
596 validaciones. </para>
600 <para> Para mayor información sobre validadores, vea la <link
601 linkend="zend.validate.introduction">documentación de
602 Zend_Validate</link> . </para>
605 <title>Usando Zend_Form_Elements como validador de propósito
609 <classname>Zend_Form_Element</classname> implementa
610 <classname>Zend_Validate_Interface</classname> ,
611 significando un elemento puede también usarse como un validador
612 en otro, cadenas de validación no relacionadas al formulario.
616 <para>Métodos asociados con validación incluyen:</para>
621 <methodname>setRequired($flag)</methodname> y
622 <methodname>isRequired()</methodname> permiten
623 establecer y recuperar el estado de la bandera 'required'.
624 Cuando se le asigna un booleano <constant>TRUE</constant> ,
625 esta bandera requiere que el elemento esté presente en la
626 información procesada por <classname>Zend_Form</classname> .
632 <methodname>setAllowEmpty($flag)</methodname> y
633 <methodname>getAllowEmpty()</methodname> permiten
634 modificar el comportamiento de elementos opcionales (p.e.,
635 elementos donde la bandera required es <constant>FALSE</constant>). Cuando la
636 bandera 'allow empty' es <constant>TRUE</constant> , valores
637 vacíos no pasarán la cadena de validadores. </para>
642 <methodname>setAutoInsertNotEmptyValidator($flag)</methodname>
643 permite especificar si realmente un validador 'NotEmpty'
644 será añadido el inicio de la cadena de validaciones cuando
645 un elemento es requerido. Por defecto, esta bandera es
646 <constant>TRUE</constant> . </para>
651 <methodname>addValidator($nameOrValidator,
652 $breakChainOnFailure = false, array $options =
659 <methodname>addValidators(array $validators)</methodname>
665 <methodname>setValidators(array $validators)</methodname>
666 (sobreescribe todos los validadores) </para>
671 <methodname>getValidator($name)</methodname> (recupera un
672 objeto validador por nombre) </para>
677 <methodname>getValidators()</methodname> (recupera todos los
683 <methodname>removeValidator($name)</methodname> (elimina un
684 validador por nombre) </para>
689 <methodname>clearValidators()</methodname> (elimina todos
690 los validadores) </para>
694 <sect3 id="zend.form.elements.validators.errors">
695 <title>Errores de mensaje personalizados</title>
697 <para>Alguna veces, querrá especificar uno o más mensajes de error
698 para usarlos en lugar de los mensajes de error generados por los
699 validadores adjuntos a los elementos. Adicionalmente, algunas
700 veces usted mismo querrá marcar al elemento como inválido. A
701 partir de 1.6.0, esta funcionalidad es posible vía los
702 siguientes métodos.</para>
707 <methodname>addErrorMessage($message)</methodname> :
708 añade un mensaje de error para mostrarlos en forma de
709 errores de validación. Puede llamarlo más de una vez, y
710 los nuevos mensajes nuevos son añadidos a la pila.
716 <methodname>addErrorMessages(array
717 $messages)</methodname> : añade múltiples mensajes
718 de error para mostrarlos en forma de errores de
724 <methodname>setErrorMessages(array
725 $messages)</methodname> : añade múltiples mensajes
726 de error para mostrarlos en forma de errores de
727 validación, sobreescribiendo todos los mensajes de error
728 previamente establecidos. </para>
733 <methodname>getErrorMessages()</methodname> : recupera
734 la lista de mensajes de error personalizados que fueron
740 <methodname>clearErrorMessages()</methodname> : remueve
741 todos los mensajes de error personalizados que hayan
742 sido definidos. </para>
747 <methodname>markAsError()</methodname> : marca al
748 elemento como que falló la validación. </para>
753 <methodname>hasErrors()</methodname> : determina si el
754 elemento ha fallado la validación o ha sido marcado como
760 <methodname>addError($message)</methodname> : añade un
761 mensaje a la pila de mensaje de error personalizados y
762 marca al elemento como inválido. </para>
767 <methodname>addErrors(array $messages)</methodname> :
768 añade varios mensajes a la pila de mensajes de error
769 personalizados y marca al elemento como inválido.
775 <methodname>setErrors(array $messages)</methodname> :
776 sobreescribe el mensaje de error personalizado en la
777 pila con los mensajes previstos y marca al elemento como
782 <para>Todos los errores establecidos de este modo pueden ser
783 traducidos. Adicionalmente, puede insertar el marcador "%value%"
784 para representar el valor del elemento; este valor actual del
785 elemento será sustituido cuando el mensaje de error sea
790 <sect2 id="zend.form.elements.decorators">
791 <title>Decoradores</title>
793 <para> Una dolencia particular para muchos desarrolladores web es la
794 creación del <acronym>XHTML</acronym> para formularios por ellos
795 mismos. Para cada elemento, el desarrollador necesita crear la
796 marcación para el elemento mismo, comúnmente una etiqueta (label),
797 y, si son amables con sus usuarios, la marcación para mostrar
798 mensajes de errores de validación. Cuanto más elementos en una
799 página, menos trivial se convierte esta tarea. </para>
802 <classname>Zend_Form_Element</classname> intenta resolver este
803 problema mediante el uso de "decoradores". Los decoradores son
804 clases simples que tienen métodos de acceso al elemento y métodos
805 para generar el contenido. Para obtener mayor información sobre cómo
806 trabajan los decoradores, consulte por favor la sección sobre <link
807 linkend="zend.form.decorators">Zend_Form_Decorator</link> . </para>
809 <para> Los decoradores usados por defecto por
810 <classname>Zend_Form_Element</classname> son: </para>
815 <emphasis>ViewHelper</emphasis> : especifica un view helper
816 que usar para general el elemento. El atributo 'helper' del
817 elemento puede usarse para especificar qué auxiliar vista
818 usar. Por defecto, <classname>Zend_Form_Element</classname>
819 especifica el auxiliar vista 'formText', pero cada subclase
820 especifica diferentes auxiliares. </para>
825 <emphasis>Errors</emphasis> : añade mensajes de error al
827 <classname>Zend_View_Helper_FormErrors</classname> . Si
828 no está presente, no se añade nada. </para>
833 <emphasis>Description</emphasis>: añade la descripción del
834 elemento. Si no está presente, no se añade nada. Por
835 defecto, la descripción es generada dentro de una etiqueta
836 <p> con un class 'description'. </para>
841 <emphasis>HtmlTag</emphasis>: envuelve el elemento y los
842 errores en una etiqueta HTML <dd>. </para>
847 <emphasis>Label</emphasis> : añade al comienzo una etiqueta
849 <classname>Zend_View_Helper_FormLabel</classname>, y
850 envolviéndola en una etiqueta <dt>. Si ninguna
851 etiqueta es provista, solo la etiqueta de la definición es
857 <title>Decoradores por defecto no necesitan ser cargados</title>
859 <para>Por defecto, los decoradores por defecto son cargados durante
860 la inicialización del objeto. Puede deshabilitar esto pasando la
861 opción 'disableLoadDefaultDecorators' al constructor:</para>
863 <programlisting language="php"><![CDATA[
864 $element = new Zend_Form_Element('foo',
865 array('disableLoadDefaultDecorators' =>
870 <para> Esta opción puede ser combinada junto con cualquier otra
871 opción que pase, ya sea como un array de opciones o en un objeto
872 <classname>Zend_Config</classname> . </para>
875 <para>Ya que el orden en el cual los decoradores son registrados importa
876 -- el primer decorador registrado es ejecutado primero -- necesitará
877 estar seguro de registrar sus decoradores en el orden apropiado, o
878 asegurarse de que estableció las opciones de colocación en el modo
879 apropiado. Por dar un ejemplo, aquí esta el código que registran los
880 decoradores por defecto:</para>
882 <programlisting language="php"><![CDATA[
883 $this->addDecorators(array(
886 array('Description', array('tag' => 'p', 'class' => 'description')),
887 array('HtmlTag', array('tag' => 'dd')),
888 array('Label', array('tag' => 'dt')),
892 <para>El contenido inicial es creado por el decorador 'ViewHelper', que
893 crea el propio elemento. En seguida, el decorador 'Errors' consulta
894 los mensajes de error del elemento, y, si hay alguno presente, los
895 pasa al auxiliar vista 'FormErrors' para mostrarlos. Si una
896 descripción está presente, el decorador 'Description' añadirá un
897 párrafo con class 'description' conteniendo el texto descriptivo
898 para el contenido agregado. El siguiente decorador, 'HtmlTag',
899 envuelve al elemento, los errores, y la descripción en una etiqueta
900 HTML <dd>. Finalmente, el último decorador, 'label',
901 recupera la etiqueta del elemento y la pasa al auxiliar vista
902 'FormLabel', envolviéndolo en una etiqueta <dt>; por
903 default el valor es añadido al inicio del contenido. El resultado de
904 la salida básicamente se ve así:</para>
906 <programlisting language="html"><![CDATA[
907 <dt><label for="foo" class="optional">Foo</label></dt>
909 <input type="text" name="foo" id="foo" value="123" />
911 <li>"123" is not an alphanumeric value</li>
913 <p class="description">
914 This is some descriptive text regarding the element.
919 <para> Para más información sobre decoradores, lea la <link
920 linkend="zend.form.decorators"> sección de
921 Zend_Form_Decorator</link> . </para>
924 <title>Usando múltiples decoradores al mismo tiempo</title>
926 <para> Internamente, <classname>Zend_Form_Element</classname>
927 utiliza una clase decorador como mecanismo de búsqueda para la
928 recuperación de decoradores. Como resultado, no puede registrar
929 múltiples decoradores del mismo tipo; decoradores subsecuentes
930 simplemente sobreescribirán aquellos que ya existían. </para>
932 <para> Para evitar esto, puede usar <emphasis>alias</emphasis> . En
933 lugar de pasar un decorador o nombre de decorador como primer
934 argumento a <methodname>addDecorator()</methodname> , pase una
935 matriz con un solo elemento, con el alias apuntando al nombre o
936 objeto decorador: </para>
938 <programlisting language="php"><![CDATA[
940 $element->addDecorator(array('FooBar' => 'HtmlTag'),
941 array('tag' => 'div'));
943 // Y recuperandolo posteriormente:
944 $decorator = $element->getDecorator('FooBar');
947 <para> En los métodos <methodname>addDecorators()</methodname> y
948 <methodname>setDecorators()</methodname> , necesitará pasar
949 la opción 'decorator' en la matriz representando el decorador: </para>
951 <programlisting language="php"><![CDATA[
952 // Y dos decoradores 'HtmlTag', 'FooBar' como alias:
953 $element->addDecorators(
954 array('HtmlTag', array('tag' => 'div')),
956 'decorator' => array('FooBar' => 'HtmlTag'),
957 'options' => array('tag' => 'dd')
961 // Y recuperándolos posteriormente:
962 $htmlTag = $element->getDecorator('HtmlTag');
963 $fooBar = $element->getDecorator('FooBar');
967 <para>Métodos asociados con decoradores incluyen:</para>
972 <methodname>addDecorator($nameOrDecorator, array $options =
979 <methodname>addDecorators(array $decorators)</methodname>
985 <methodname>setDecorators(array $decorators)</methodname>
986 (sobreescribe todos los decoradores) </para>
991 <methodname>getDecorator($name)</methodname> (recupera un
992 objeto decorador por su nombre) </para>
997 <methodname>getDecorators()</methodname> (recupera todos los
1003 <methodname>removeDecorator($name)</methodname> (elimina un
1004 decorador por su nombre) </para>
1009 <methodname>clearDecorators()</methodname> (elimina todos
1010 los decoradores) </para>
1015 <classname>Zend_Form_Element</classname> también utiliza la
1016 sobrecarga para permitir generar decoradores específicos.
1017 <methodname>__call()</methodname> interceptará métodos que
1018 comiencen con el texto 'render' y utilizará el resto del nombre del
1019 método para buscar un decorador; si se encuentra, entonces será
1020 generado <emphasis>sólo ese</emphasis> decorador. Cualquier
1021 argumento pasado al llamado del método será usado como contenido
1022 para pasar al método <methodname>render()</methodname> del
1023 decorador. Como ejemplo: </para>
1025 <programlisting language="php"><![CDATA[
1026 // Genera solo el decorador ViewHelper:
1027 echo $element->renderViewHelper();
1029 // Genera solo el decorador HtmlTag, pasándole contenido:
1030 echo $element->renderHtmlTag("This is the html tag content");
1031 ]]></programlisting>
1033 <para>Si el decorador no existe, una excepción es lanzada.</para>
1036 <sect2 id="zend.form.elements.metadata">
1037 <title>Metadatos y atributos</title>
1040 <classname>Zend_Form_Element</classname> manipula una variedad de
1041 atributos y medatados del elemento. Atributos básicos incluyen: </para>
1046 <emphasis>name</emphasis> : el nombre del elemento. Emplea
1047 los métodos de acceso <methodname>setName()</methodname> y
1048 <methodname>getName()</methodname> . </para>
1053 <emphasis>label</emphasis> : la etiqueta del elemento.
1054 Emplea los métodos de acceso
1055 <methodname>setLabel()</methodname> y
1056 <methodname>getLabel()</methodname> . </para>
1061 <emphasis>order</emphasis> : el índice en el cual los
1062 elementos deben ir mostrándose en el formulario. Emplea los
1063 métodos de acceso <methodname>setOrder()</methodname> y
1064 <methodname>getOrder()</methodname> . </para>
1069 <emphasis>value</emphasis> : El valor del elemento actual.
1070 Emplea los métodos de acceso
1071 <methodname>setValue()</methodname> y
1072 <methodname>getValue()</methodname> . </para>
1077 <emphasis>description</emphasis> : una descripción del
1078 elemento; a menudo utilizada para proveer un tooltip o ayuda
1079 contextual con javascript describiendo el propósito del
1080 elemento. Emplea los métodos de acceso
1081 <methodname>setDescription()</methodname> y
1082 <methodname>getDescription()</methodname> . </para>
1087 <emphasis>required</emphasis> : bandera que indica si un
1088 elemento es requerido o no cuando se efectúa la validación
1089 del formulario. Emplea los métodos de acceso
1090 <methodname>setRequired()</methodname> y
1091 <methodname>getRequired()</methodname> . Esta bandera es
1092 <constant>FALSE</constant> por defecto. </para>
1097 <emphasis>allowEmpty</emphasis> : bandera indicando si un
1098 elemento no-requerido (opcional) debe intentar validar o no
1099 valores vacíos. Cuando es <constant>TRUE</constant> , y la
1100 bandera required es <constant>FALSE</constant> , valores
1101 vacíos no pasarán la cadena de validación, y se supone
1102 verdadero. Emplea los métodos de acceso
1103 <methodname>setAllowEmpty()</methodname> y
1104 <methodname>getAllowEmpty()</methodname> . Esta bandera
1105 es <constant>TRUE</constant> por defecto. </para>
1110 <emphasis>autoInsertNotEmptyValidator</emphasis> : bandera
1111 indicando insertar o no un validador 'NotEmpty' cuando un
1112 elemento es requerido. Por defecto, esta bandera es
1113 <constant>TRUE</constant> . Establezca la bandera con
1114 <methodname>setAutoInsertNotEmptyValidator($flag)</methodname>
1115 y determine el valor con
1116 <methodname>autoInsertNotEmptyValidator()</methodname> .
1121 <para> Los elementos del formulario pueden requerir metainformación
1122 adicional. Para elementos <acronym>XHTML</acronym> del formuladio,
1123 por ejemplo, puede querer especificar atributos como el class o id.
1124 Para facilitar esto hay un conjunto de métodos de acceso: </para>
1129 <emphasis>setAttrib($name, $value)</emphasis> : añade un
1135 <emphasis>setAttribs(array $attribs)</emphasis> : como
1136 addAttribs(), pero sobreescribiendo </para>
1141 <emphasis>getAttrib($name)</emphasis> : recupera el valor de
1142 solo un atributo </para>
1147 <emphasis>getAttribs()</emphasis> : recupera todos los
1148 atributos como pares clave/valor </para>
1152 <para> La mayoría de las veces, como sea, puede simplemente acceder a
1153 ellos como propiedades de objeto, ya que
1154 <classname>Zend_Form_Element</classname> utiliza la sobrecarga
1155 para facilitar el acceso a ellos: </para>
1157 <programlisting language="php"><![CDATA[
1158 // Equivalente a $element->setAttrib('class', 'text'):
1159 $element->class = 'text;
1160 ]]></programlisting>
1162 <para>Por defecto, todos los atributos son pasados al auxiliar vista
1163 usado por el elemento durante la generación, y generados como
1164 atributos de la etiqueta del elemento.</para>
1167 <sect2 id="zend.form.elements.standard">
1168 <title>Elementos Estándar</title>
1171 <classname>Zend_Form</classname> contiene un buen número de
1172 elementos estándar; por favor lea el capítulo <link
1173 linkend="zend.form.standardElements">Elementos Estándar</link>
1174 para todos los detalles. </para>
1177 <sect2 id="zend.form.elements.methods">
1178 <title>Métodos de Zend_Form_Element</title>
1181 <classname>Zend_Form_Element</classname> tiene muchos, muchos
1182 métodos. Lo que sigue es un sumario de sus funciones, agrupados por
1187 <para>Configuración:</para>
1191 <methodname>setOptions(array $options)</methodname>
1196 <methodname>setConfig(Zend_Config
1197 $config)</methodname>
1208 <methodname>setTranslator(Zend_Translate_Adapter
1209 $translator = null)</methodname>
1214 <methodname>getTranslator()</methodname>
1219 <methodname>setDisableTranslator($flag)</methodname>
1224 <methodname>translatorIsDisabled()</methodname>
1231 <para>Propiedades:</para>
1235 <methodname>setName($name)</methodname>
1240 <methodname>getName()</methodname>
1245 <methodname>setValue($value)</methodname>
1250 <methodname>getValue()</methodname>
1255 <methodname>getUnfilteredValue()</methodname>
1260 <methodname>setLabel($label)</methodname>
1265 <methodname>getLabel()</methodname>
1270 <methodname>setDescription($description)</methodname>
1275 <methodname>getDescription()</methodname>
1280 <methodname>setOrder($order)</methodname>
1285 <methodname>getOrder()</methodname>
1290 <methodname>setRequired($flag)</methodname>
1295 <methodname>getRequired()</methodname>
1300 <methodname>setAllowEmpty($flag)</methodname>
1305 <methodname>getAllowEmpty()</methodname>
1310 <methodname>setAutoInsertNotEmptyValidator($flag)</methodname>
1315 <methodname>autoInsertNotEmptyValidator()</methodname>
1320 <methodname>setIgnore($flag)</methodname>
1325 <methodname>getIgnore()</methodname>
1330 <methodname>getType()</methodname>
1335 <methodname>setAttrib($name, $value)</methodname>
1340 <methodname>setAttribs(array $attribs)</methodname>
1345 <methodname>getAttrib($name)</methodname>
1350 <methodname>getAttribs()</methodname>
1357 <para>Cargadores y rutas de plugin:</para>
1361 <methodname>setPluginLoader(Zend_Loader_PluginLoader_Interface
1362 $loader, $type)</methodname>
1367 <methodname>getPluginLoader($type)</methodname>
1372 <methodname>addPrefixPath($prefix, $path, $type =
1378 <methodname>addPrefixPaths(array $spec)</methodname>
1385 <para>Validación:</para>
1389 <methodname>addValidator($validator,
1390 $breakChainOnFailure = false, $options =
1391 array())</methodname>
1396 <methodname>addValidators(array
1397 $validators)</methodname>
1402 <methodname>setValidators(array
1403 $validators)</methodname>
1408 <methodname>getValidator($name)</methodname>
1413 <methodname>getValidators()</methodname>
1418 <methodname>removeValidator($name)</methodname>
1423 <methodname>clearValidators()</methodname>
1428 <methodname>isValid($value, $context =
1434 <methodname>getErrors()</methodname>
1439 <methodname>getMessages()</methodname>
1446 <para>Filtros:</para>
1450 <methodname>addFilter($filter, $options =
1451 array())</methodname>
1456 <methodname>addFilters(array $filters)</methodname>
1461 <methodname>setFilters(array $filters)</methodname>
1466 <methodname>getFilter($name)</methodname>
1471 <methodname>getFilters()</methodname>
1476 <methodname>removeFilter($name)</methodname>
1481 <methodname>clearFilters()</methodname>
1488 <para>Generación:</para>
1492 <methodname>setView(Zend_View_Interface $view =
1498 <methodname>getView()</methodname>
1503 <methodname>addDecorator($decorator, $options =
1509 <methodname>addDecorators(array
1510 $decorators)</methodname>
1515 <methodname>setDecorators(array
1516 $decorators)</methodname>
1521 <methodname>getDecorator($name)</methodname>
1526 <methodname>getDecorators()</methodname>
1531 <methodname>removeDecorator($name)</methodname>
1536 <methodname>clearDecorators()</methodname>
1541 <methodname>render(Zend_View_Interface $view =
1550 <sect2 id="zend.form.elements.config">
1551 <title>Configuración</title>
1553 <para> El constructor de <classname>Zend_Form_Element</classname> acepta
1554 tanto una matriz de opciones como un objeto
1555 <classname>Zend_Config</classname> conteniendo opciones, y esto
1556 puede configurarse usando <methodname>setOptions()</methodname> o
1557 <methodname>setConfig()</methodname> . Hablando de manera
1558 general, las claves son nombradas de la siguiente manera: </para>
1562 <para> Si 'set' + clave se refiere a un método de
1563 <classname>Zend_Form_Element</classname> , entonces el
1564 valor provisto será pasado a el método. </para>
1568 <para>De otra manera, el valor será usado para establecer un
1573 <para>Excepciones a la regla incluyen las siguientes:</para>
1578 <methodname>prefixPath</methodname> será pasado a
1579 <methodname>addPrefixPaths()</methodname>
1584 <para>Los siguientes setters no pueden establecerse de esta
1590 <methodname>setAttrib</methodname> (aunque
1591 <methodname>setAttribs</methodname>
1592 <emphasis>funcionará</emphasis>
1598 <methodname>setConfig</methodname>
1604 <methodname>setOptions</methodname>
1610 <methodname>setPluginLoader</methodname>
1616 <methodname>setTranslator</methodname>
1622 <methodname>setView</methodname>
1629 <para>Como ejemplo, aquí esta un archivo de configuración pasado para
1630 cada tipo de dato configurable:</para>
1632 <programlisting language="ini"><![CDATA[
1640 autoInsertNotEmptyValidator = true
1641 description = "Foo elements are for examples"
1644 attribs.class = "element"
1645 ; sets 'onclick' attribute
1646 onclick = "autoComplete(this, '/form/autocomplete/element')"
1647 prefixPaths.decorator.prefix = "My_Decorator"
1648 prefixPaths.decorator.path = "My/Decorator/"
1649 disableTranslator = 0
1650 validators.required.validator = "NotEmpty"
1651 validators.required.breakChainOnFailure = true
1652 validators.alpha.validator = "alpha"
1653 validators.regex.validator = "regex"
1654 validators.regex.options.pattern = "/^[A-F].*/$"
1655 filters.ucase.filter = "StringToUpper"
1656 decorators.element.decorator = "ViewHelper"
1657 decorators.element.options.helper = "FormText"
1658 decorators.label.decorator = "Label"
1659 ]]></programlisting>
1662 <sect2 id="zend.form.elements.custom">
1663 <title>Elementos personalizados</title>
1665 <para> Usted puede crear sus propios elementos personalizados
1666 simplemente extendiendo la clase
1667 <classname>Zend_Form_Element</classname> . Las razones comunes
1668 para hacer esto incluyen: </para>
1672 <para>Elementos que comparten validadores y/o filtros comunes
1677 <para>Elementos que tienen decoradores con funcionalidad
1678 personalizada</para>
1682 <para> Hay dos métodos típicamente usados para extender un elemento:
1683 <methodname>init()</methodname> , el cual puede usarse para
1684 añadir una lógica de inicialización personalizada a su elemento, y
1685 <methodname>loadDefaultDecorators()</methodname> , el cual puede
1686 usarse para establecer una lista de decoradores usados por su
1687 elemento de manera predeterminada. </para>
1689 <para> Como un ejemplo, digamos que todos los elementos de tipo texto en
1690 un formulario que está creando, necesitan ser filtrados con
1691 <methodname>StringTrim</methodname> , validados con una
1692 expresión regular, y que quiere usar un decorador personalizado que
1693 ha creado para mostrarlos, 'My_Decorator_TextItem'; adicionalmente,
1694 tiene un número de atributos estándars, incluyendo 'size',
1695 'maxLength', y 'class' que quisiera especificar. Puede definir un
1696 elemento tal como sigue: </para>
1698 <programlisting language="php"><![CDATA[
1699 class My_Element_Text extends Zend_Form_Element
1701 public function init()
1703 $this->addPrefixPath('My_Decorator', 'My/Decorator/', 'decorator')
1704 ->addFilters('StringTrim')
1705 ->addValidator('Regex', false, array('/^[a-z0-9]{6,}$/i'))
1706 ->addDecorator('TextItem')
1707 ->setAttrib('size', 30)
1708 ->setAttrib('maxLength', 45)
1709 ->setAttrib('class', 'text');
1712 ]]></programlisting>
1714 <para>Entonces puede informar a su objeto formulario acerca del prefijo
1715 de ruta para elementos de ese tipo, y comenzar creando
1718 <programlisting language="php"><![CDATA[
1719 $form->addPrefixPath('My_Element', 'My/Element/', 'element')
1720 ->addElement('foo', 'text');
1721 ]]></programlisting>
1723 <para> El elemento 'foo' será ahora del tipo
1724 <methodname>My_Element_Text</methodname> , y mostrará el
1725 comportamiento que ha especificado. </para>
1727 <para> Otro método que puede querer sobreescribir cuando extienda
1728 <classname>Zend_Form_Element</classname> es el método
1729 <methodname>loadDefaultDecorators()</methodname> . Este método
1730 carga condicionalmente un grupo de decoradores predefinidos para su
1731 elemento; puede querer sustituir su propio decorador en su clase
1734 <programlisting language="php"><![CDATA[
1735 class My_Element_Text extends Zend_Form_Element
1737 public function loadDefaultDecorators()
1739 $this->addDecorator('ViewHelper')
1740 ->addDecorator('DisplayError')
1741 ->addDecorator('Label')
1742 ->addDecorator('HtmlTag',
1743 array('tag' => 'div', 'class' => 'element'));
1746 ]]></programlisting>
1748 <para> Hay muchas maneras de personalizar elementos; asegúrese de leer
1749 la documentación de la <acronym>API</acronym> de
1750 <classname>Zend_Form_Element</classname> para conocer todos los
1751 métodos disponibles. </para>