<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 20115 -->
    <!-- Reviewed: no -->
<sect1 id="zend.form.forms">
    <title>Creando formularios usando Zend_Form</title>

    <para> La clase <classname>Zend_Form</classname> es usada para agregar
        elementos de formulario, desplegar grupos y subformularios. Éstos pueden
        ejecutar las siguientes acciones en estos elementos: </para>

    <itemizedlist>
        <listitem>
            <para>Validación, incluyendo la recuperación de código y mensajes de
                error</para>
        </listitem>

        <listitem>
            <para>Agregación de valor, incluyendo el llenado de elementos y
                recuperación de valores tanto filtrados como no filtrados para
                todos los elementos</para>
        </listitem>

        <listitem>
            <para>Iteración sobre todos los elementos, en el orden en el cual
                han sido introducidos o basados en el orden recuperado de cada
                elemento</para>
        </listitem>

        <listitem>
            <para>Generando el formulario entero, ya sea por un simple decorador
                que ejecuta un muestreo personalizado o por iteración sobre cada
                elemento del formulario</para>
        </listitem>
    </itemizedlist>

    <para> Mientras los formularios creados con <classname>Zend_Form</classname>
        pueden ser complejos, probablemente su mejor uso es para formularios
        simples; es mejor utilizarlo para desarrollar aplicaciones rápidas (RAD)
        y de prototipado. </para>

    <para>En lo más básico, simplemente instancie el objeto formulario:</para>

    <programlisting language="php"><![CDATA[
// Objeto form genérico:
$form = new Zend_Form();

// Objeto form personalizado:
$form = new My_Form()
]]></programlisting>

    <para>Opcionalmente puede pasarlo en la configuración, la cual será usada
        para establecer el estado del objeto, potencialmente así como también
        crear nuevos elementos:</para>

    <programlisting language="php"><![CDATA[
// Pasando opciones en la configuración:
$form = new Zend_Form($config);
]]></programlisting>

    <para>
        <classname>Zend_Form</classname> es iterable, e iterará sobre elementos,
        grupos que mostrar y subformularios, usando el orden en el cual han sido
        registrados y en cualquier índice de orden que cada uno pueda tener.
        Esto es útil en casos donde desee generar los elementos manualmente en
        el orden apropiado. </para>

    <para> La magia de <classname>Zend_Form</classname> radica en la habilidad
        para servir como fábrica para elementos y grupos, así como también la
        habilidad de generarse a sí mismo a través de decoradores. </para>

    <sect2 id="zend.form.forms.plugins">
        <title>Cargadores de Plugin</title>
        <para>
            <classname>Zend_Form</classname> hace uso de
                <classname>Zend_Loader_PluginLoader</classname> para permitir a
            los desarroladores especificar la ubicación de elementos y
            decoradores alternativos. Cada uno tiene su propio plugin loader
            asociado, y métodos de acceso genéricos son usados para recuperar y
            modificar cada uno. </para>

        <para>Los siguientes tipos de cargadores son usados con los variados
            métodos del plugin loader: 'element' y 'decorator'. Los nombres de
            los tipos no distinguen mayúsculas de minúsculas.</para>

        <para>Los métodos usados para interactuar con plugin loaders son los
            siguientes:</para>

        <itemizedlist>
            <listitem>
                <para>
                    <methodname>setPluginLoader($loader, $type)</methodname> :
                    $loader es el propio objeto plugin loader, mientras
                        <varname>$type</varname> es uno de los tipos
                    especificados arriba. Esto establece el plugin loader para
                    el tipo dado al objeto loader recién especificado. </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>getPluginLoader($type)</methodname> : recupera
                    el plugin loader asociado con <varname>$type</varname> .
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>addPrefixPath($prefix, $path, $type =
                        null)</methodname> : agrega una asociación prefijo/ruta
                    al loader especificado por <varname>$type</varname> . Si
                        <varname>$type</varname> es nulo, intentará añadir una
                    ruta a todos los loaders, añadiendo el prefijo "_Element" y
                    "_Decorator"; y añadiendo la ruta con "Element/" y
                    "Decorator/". Si tiene todas sus clases form element extras
                    bajo una jerarquía común, éste es un método coveniente para
                    establecer el prefijo de base para ellas. </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>addPrefixPaths(array $spec)</methodname> : le
                    permite añadir varias rutas en uno o mas plugin loaders. Se
                    espera que cada elemento del array sea un array con las
                    claves 'path', 'prefix' y 'type'. </para>
            </listitem>
        </itemizedlist>

        <para> Adicionalmente, puede especificar prefijos de rutas para todos
            los elementos y mostrar grupos creados a través de una instancia de
                <classname>Zend_Form</classname> usando los siguientes métodos: </para>

        <itemizedlist>
            <listitem>
                <para>
                    <methodname>addElementPrefixPath($prefix, $path, $type =
                        null)</methodname> : Igual que
                        <methodname>addPrefixPath()</methodname> , debe
                    especificar un prefijo y ruta de clase.
                        <varname>$type</varname> , cuando se especifica, tiene
                    que ser uno de los tipos plugin loader especificados por
                        <classname>Zend_Form_Element</classname> ; vea la <link
                        linkend="zend.form.elements.loaders">sección elemento
                        plugins </link> para más información de valores válidos
                    para <varname>$type</varname> . Si <varname>$type</varname>
                    no es especificado, el método asumirá que es un prefijo
                    general para todos los tipos. </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>addDisplayGroupPrefixPath($prefix,
                        $path)</methodname> : Igual que
                        <methodname>addPrefixPath()</methodname> , debe
                    especificar un prefijo y ruta de clase; sin embargo, dado
                    que los grupos de visualización (display groups) sólo
                    soportan decoradores como plugins, <varname>$type</varname>
                    no es necesario. </para>
            </listitem>
        </itemizedlist>

        <para> Elementos y decoradores personalizados son una manera fácil de
            compartir funcionalidad entre formularios y encapsular funcionalidad
            personalizada. Vea el <link
                linkend="zend.form.elements.loaders.customLabel">ejemplo de
                Etiqueta Personalizada</link> en la documentación de elementos
            para un ejemplo de cómo elementos personalizados pueden ser usados
            como reemplazos para clases estándar. </para>
    </sect2>

    <sect2 id="zend.form.forms.elements">
        <title>Elementos</title>
        <para>
            <classname>Zend_Form</classname> proporciona varios métodos de
            acceso para añadir y eliminar elementos de el formulario. Éstos
            pueden tomar instancias de objetos de elemento o servir como
            fábricas para instanciar el objeto elemento a sí mismo. </para>

        <para> El método más básico para añadir un elemento es
                <methodname>addElement()</methodname> . Este método puede tomar
            también un objeto de tipo <classname>Zend_Form_Element</classname>
            (o de una clase extendiendo <classname>Zend_Form_Element</classname>
            ), o argumentos para construir un nuevo elemento -- incluyendo el
            elemento tipo, nombre y algunas opciones de configuración. </para>

        <para>Como algunos ejemplos:</para>

        <programlisting language="php"><![CDATA[
// Usando un elemento instanciado:
$element = new Zend_Form_Element_Text('foo');
$form->addElement($element);

// Usando una fábrica
//
// Crea un elemento de tipo Zend_Form_Element_Text con el
// nombre de 'foo':
$form->addElement('text', 'foo');

// Pasa una opción etiqueta al elemento:
$form->addElement('text', 'foo', array('label' => 'Foo:'));
]]></programlisting>

        <note>
            <title>addElement() Implementa una Interfaz Fluida</title>

            <para>
                <methodname>addElement()</methodname> implementa una interfaz
                fluida; es decir, retorna el objeto
                    <classname>Zend_Form</classname> y no un elemento. Esto se
                ha hecho para permitirle encadenar multiples métodos
                addElement() u otros métodos formulario que implementen una
                interfaz fluida (todos los establecedores en Zend_Form
                implementan el patrón). </para>

            <para> Si desea retornar el elemento, use
                    <methodname>createElement()</methodname> , el cual es
                esbozado abajo. Tenga en cuenta de cualquier manera que
                    <methodname>createElement()</methodname> no adjunta el
                elemento al formulario. </para>

            <para> Internamente, <methodname>addElement()</methodname> en
                realidad emplea <methodname>createElement()</methodname> para
                crear el elemento antes de adjuntarlo al formulario. </para>
        </note>

        <para> Una vez que el elemento ha sido añadido al formulario, puede
            recuperarlo por el nombre. Puede también finalizar usando el método
                <methodname>getElement()</methodname> o usando sobrecarga para
            acceder al elemento como una propiedad de objeto: </para>

        <programlisting language="php"><![CDATA[
// getElement():
$foo = $form->getElement('foo');

// Como propiedad del objeto:
$foo = $form->foo;
]]></programlisting>

        <para> Ocasionalmente, se quiere crear un elemento sin adjuntarlo al
            formulario (para instanciar, si se desea hacer uso de las rutas de
            plugin introducidas con el formulario, pero después se desea
            adjuntar el objeto al subformulario). El método
                <methodname>createElement()</methodname> permite hacer eso: </para>

        <programlisting language="php"><![CDATA[
// $username llega a ser un objeto Zend_Form_Element_Text:
$username = $form->createElement('text', 'username');
]]></programlisting>

        <sect3 id="zend.form.forms.elements.values">
            <title>Llenar y recuperar valores</title>

            <para> Después de validar el formulario, originalmente se necesitará
                recuperar los valores para poder ejecutar otras operaciones, tal
                como actualizar una base de datos o notificar un servicio web.
                Se pueden recuperar todos los valores para todos los elementos
                usando <methodname>getValues()</methodname> ;
                    <methodname>getValue($name)</methodname> le permite
                recuperar un solo valor del elemento por su nombre: </para>

            <programlisting language="php"><![CDATA[
// Obtener todos los valores:
$values = $form->getValues();

// Obtener sólo los valores del elemento 'foo':
$value = $form->getValue('foo');
]]></programlisting>

            <para> A veces se quiere llenar el formulario con valores
                especificos antes de generarlos. Éstos pueden ser llevados a
                cabo ya sea con los métodos
                    <methodname>setDefaults()</methodname> o
                    <methodname>populate()</methodname> : </para>

            <programlisting language="php"><![CDATA[
$form->setDefaults($data);
$form->populate($data);
]]></programlisting>

            <para> Por otro lado, si se quisera limpiar el formulario antes de
                llenarlo o validarlo; se puede realizar usando el método
                    <methodname>reset()</methodname> : </para>

            <programlisting language="php"><![CDATA[
$form->reset();
]]></programlisting>
        </sect3>

        <sect3 id="zend.form.forms.elements.global">
            <title>Operaciones Globales</title>

            <para>Ocasionalemnte se necesitarán ciertas operaciones que afecten
                a todos los elementos. Escenarios comunes incluyen la necesidad
                de determinar rutas de acceso al prefijo complemento para todos
                los elementos, determinando decoradores para todos los elementos
                y determinando filtros para todos los elementos. Como
                ejemplos:</para>

            <example id="zend.form.forms.elements.global.allpaths">
                <title>Determinando rutas de acceso de prefijos para todos los
                    elementos</title>

                <para>Se puede determinar rutas de acceso para prefijos para
                    todos los elementos por tipo, o usando un prefijo global.
                    Como ejemplos:</para>

                <programlisting language="php"><![CDATA[
// Determinar la ruta de acceso de prefijos global
// Crear rutas de acceso para los prefijos My_Foo_Filter, My_Foo_Validate,
// y My_Foo_Decorator
$form->addElementPrefixPath('My_Foo', 'My/Foo/');

// Sólo rutas de acceso de filtros:
$form->addElementPrefixPath('My_Foo_Filter',
                            'My/Foo/Filter',
                            'filter');

// Sólo rutas de acceso de validadores:
$form->addElementPrefixPath('My_Foo_Validate',
                            'My/Foo/Validate',
                            'validate');

// Sólo rutas de acceso de decoradores:
$form->addElementPrefixPath('My_Foo_Decorator',
                            'My/Foo/Decorator',
                            'decorator');
]]></programlisting>
            </example>

            <example id="zend.form.forms.elements.global.decorators">
                <title>Determinando Decoradores para todos los elementos</title>

                <para> Se pueden determinar decoradores para todos los
                    elementos. <methodname>setElementDecorators()</methodname>
                    acepta una matriz de decoradores, solo como
                        <methodname>setDecorators()</methodname> , y reescribirá
                    cualquier decorador previamente determinado en cada
                    elemento. En este ejemplo, determinamos los decoradores para
                    simplificar una ViewHelper y una Label: </para>

                <programlisting language="php"><![CDATA[
$form->setElementDecorators(array(
    'ViewHelper',
    'Label'
));
]]></programlisting>
            </example>

            <example id="zend.form.forms.elements.global.decoratorsFilter">
                <title>Determinando decoradores para algunos elementos</title>

                <para> Pueden determinarse también decoradores para un
                    subconjunto de elementos, ya sea por inclusión o exclusión.
                    El segundo argumento
                        <methodname>setElementDecorators()</methodname> puede
                    ser un array de nombres de elemento; por defecto,
                    especificar un array de ese tipo determinará los decoradores
                    especificados en esos elementos solamente. Puede tambien
                    pasar un tercer elemento, una bandera indicando si esta
                    lista de elementos es para propósitos de inclusión o
                    exclusión; si es falso, decorará todos los elementos
                    <emphasis>excepto</emphasis> los pasados en la lista,
                    Como uso estándar del método, cualquier decorador pasado
                    reescribirá cualquier decorador previamente determinado en
                    cada elemento. </para>

                <para>En el siguiente fragmento, indicamos que queremos los
                    decoradores ViewHelper y Label para los elementos 'foo' y
                    'bar':</para>

                <programlisting language="php"><![CDATA[
$form->setElementDecorators(
    array(
        'ViewHelper',
        'Label'
    ),
    array(
        'foo',
        'bar'
    )
);
]]></programlisting>

                <para> Por otro lado, con este fragmento, indicaremos que
                    queremos usar solamente los decoradores ViewHelper y Label
                    para cada elemento <emphasis>excepto</emphasis> los
                    elementos 'foo' y 'bar': </para>

                <programlisting language="php"><![CDATA[
$form->setElementDecorators(
    array(
        'ViewHelper',
        'Label'
    ),
    array(
        'foo',
        'bar'
    ),
    false
);
]]></programlisting>
            </example>

            <note>
                <title>Algunos Decoradores son Inapropiados para algunos
                    Elementos</title>

                <para> Mientras <methodname>setElementDecorators()</methodname>
                    puede parecer una buena solución, existen algunos casos
                    donde puede terminar con resultados inesperados, Por
                    ejemplo, los muchos elementos botones (Submit, Button,
                    Reset), actualmente usan la etiqueta como el valor del botón
                    y sólo usan los decoradores ViewHelper y DtDdWrapper --
                    previniendo una etiqueta adicional, errores, y sugerencias
                    de ser generadas; el ejemplo de arriba podría duplicar algún
                    contenido (la etiqueta). </para>

                <para>Se puede usar el array de inclusión/exclusión para superar
                    este problema como se ha notado en el ejemplo
                    anterior.</para>

                <para>Entonces, use este método sabiamente y dése cuenta de que
                    puede necesitar excluir o cambiar manualmente algunos
                    elementos decoradores para prevenir una salida no deseada.
                </para>
            </note>

            <example id="zend.form.forms.elements.global.filters">
                <title>Determinando Filtros para todos los Elementos</title>

                <para> En muchos casos, puede quererse aplicar el mismo filtro a
                    todos los elementos; un caso común es
                        <methodname>trim()</methodname> a todos los valores: </para>

                <programlisting language="php"><![CDATA[
$form->setElementFilters(array('StringTrim'));
]]></programlisting>
            </example>
        </sect3>

        <sect3 id="zend.form.forms.elements.methods">
            <title>Métodos para Interactuar con los Elementos</title>

            <para>Los siguientes métodos pueden ser usados para interactuar con
                los elementos:</para>

            <itemizedlist>
                <listitem>
                    <para>
                        <methodname>createElement($element, $name = null,
                            $options = null)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>addElement($element, $name = null, $options
                            = null)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>addElements(array $elements)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>setElements(array $elements)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>getElement($name)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>getElements()</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>removeElement($name)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>clearElements()</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>setDefaults(array $defaults)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>setDefault($name, $value)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>getValue($name)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>getValues()</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>getUnfilteredValue($name)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>getUnfilteredValues()</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>setElementFilters(array
                            $filters)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>setElementDecorators(array
                            $decorators)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>addElementPrefixPath($prefix, $path, $type =
                            null)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>addElementPrefixPaths(array
                            $spec)</methodname>
                    </para>
                </listitem>
            </itemizedlist>
        </sect3>
    </sect2>

    <sect2 id="zend.form.forms.displaygroups">
        <title>Grupos de visualización (display groups)</title>

        <para>Los grupos de visualización (display groups) son una manera de
            crear grupos virtuales de elementos para propósitos de
            visualización. Todos los elementos quedan accesibles por nombre en
            el formulario, pero cuando interactúan o se ejecutan sobre el
            formulario, cualquiera de los elementos en un grupos de
            visualización son generados juntos. El caso más común de uso es
            agrupando los elementos en fieldsets. (TODO)</para>

        <para> La clase base para los grupos de visualización es
                <classname>Zend_Form_DisplayGroup</classname> . Mientras puede
            ser instanciado directamente, es mejor usar el método
                <methodname>addDisplayGroup()</methodname> de la clase
                <classname>Zend_Form</classname> . Este método toma un array de
            elementos como primer argumento y el nombre para el grupo de
            visualización como segundo argumento. Opcionalmente, se puede pasar
            en una array de opciones o en un objeto
                <classname>Zend_Config</classname> como tercer argumento. </para>

        <para>Asumiendo que los elementos 'username' y 'password' has sido
            determinados en el formulario, el siguiente código podría agrupar
            estos elementos en un grupo de visualización 'login':</para>

        <programlisting language="php"><![CDATA[
$form->addDisplayGroup(array('username', 'password'), 'login');
]]></programlisting>

        <para> Puede acceder a los grupos de visualización usando el método
                <methodname>getDisplayGroup()</methodname> , o mediante la
            sobrecarga usando el nombre del grupo de visualización: </para>

        <programlisting language="php"><![CDATA[
// Usando getDisplayGroup():
$login = $form->getDisplayGroup('login');

// Usando sobrecarga:
$login = $form->login;
]]></programlisting>

        <note>
            <title>Decoradores por defecto que no necesitan ser cargados</title>

            <para>Por defecto, los grupos de visualización son cargados durante
                la inicialización del objeto. Se puede deshabilitar pasando la
                opción 'disableLoadDefaultDecorators' cuando se crea un grupo de
                visualización:</para>

            <programlisting language="php"><![CDATA[
$form->addDisplayGroup(
    array('foo', 'bar'),
    'foobar',
    array('disableLoadDefaultDecorators' => true)
);
]]></programlisting>

            <para> Esta opción puede ser una mezcla con otras opciones pasadas,
                ambas como opciones de array o en el objeto
                    <classname>Zend_Config</classname>
            </para>
        </note>

        <sect3 id="zend.form.forms.displaygroups.global">
            <title>Operaciones Globales</title>

            <para>Al igual que los elementos, existen algunas operaciones que
                pueden afectar a todos los grupos de visualización; éstas
                incluyen determinar decoradores y fijar la ruta de acceso donde
                buscar los decoradores.</para>

            <example id="zend.form.forms.displaygroups.global.paths">
                <title>Fijando el Prefijo de Ruta del Decorador para todos los
                    Grupos de Visualización</title>

                <para> Por defecto, los grupos de visualización heredan
                    cualquier ruta de decorador que use el formulario; sin
                    embargo, si deberían buscar en una ruta alternativa, puede
                    usar el método
                        <methodname>addDisplayGroupPrefixPath()</methodname>
                    method. </para>

                <programlisting language="php"><![CDATA[
$form->addDisplayGroupPrefixPath('My_Foo_Decorator', 'My/Foo/Decorator');
]]></programlisting>
            </example>

            <example id="zend.form.forms.displaygroups.global.decorators">
                <title>Fijando Decoradores para Todos los Grupos de
                    Visualización</title>

                <para> Pueden determinarse decoradores para todos los grupos de
                    visualización,
                        <methodname>setDisplayGroupDecorators()</methodname>
                    admite un array de decoradores, al igual que
                        <methodname>setDecorators()</methodname> , y
                    sobreescribirá cualquier conjunto de decoradores previo en
                    cada grupo de visualización. En este ejemplo, fijamos los
                    decoradores a un fieldset (el decorador FormElements es
                    necesario para asegurar que los elementos son iterador): </para>

                <programlisting language="php"><![CDATA[
$form->setDisplayGroupDecorators(array(
    'FormElements',
    'Fieldset'
));
]]></programlisting>
            </example>
        </sect3>

        <sect3 id="zend.form.forms.displaygroups.customClasses">
            <title>Usando Clases de Grupos de Visualización
                Personalizadas</title>

            <para> Por defecto, <classname>Zend_Form</classname> utiliza la
                clase <classname>Zend_Form_DisplayGroup</classname> para grupos
                de visualización. Puede ocurrir que necesite extender esta clase
                con el fin de obtener una funcionalid personalizada.
                    <methodname>addDisplayGroup()</methodname> no permite pasar
                una instancia determinada, pero permite especificar la clase que
                usar como una de sus opciones, usando la clave
                'displayGroupClass': </para>

            <programlisting language="php"><![CDATA[
// Use the 'My_DisplayGroup' class
$form->addDisplayGroup(
    array('username', 'password'),
    'user',
    array('displayGroupClass' => 'My_DisplayGroup')
);
]]></programlisting>

            <para> Si la clase no ha sido todavía cargada,
                    <classname>Zend_Form</classname> intentará cargarla a través
                de <classname>Zend_Loader</classname> . </para>

            <para>También puede especificar una clase de grupo de visualización
                por defecto para usar con el formulario, de forma que todos los
                grupos de visualización creados con el objeto formulario usen
                esa clase:</para>

            <programlisting language="php"><![CDATA[
// Use the 'My_DisplayGroup' class for all display groups:
$form->setDefaultDisplayGroupClass('My_DisplayGroup');
]]></programlisting>

            <para>Esta funcionalidad puede especificarse en configuraciones como
                'defaultDisplayGroupClass', y será cargada con antelación para
                asegurar que todos los grupos de visualización usen esa
                clase.</para>
        </sect3>

        <sect3 id="zend.form.forms.displaygroups.interactionmethods">
            <title>Métodos para Interactuar con Grupos de Visualización</title>

            <para>Los siguientes métodos pueden ser usados para interactuar con
                el grupo de visualización:</para>

            <itemizedlist>
                <listitem>
                    <para>
                        <methodname>addDisplayGroup(array $elements, $name,
                            $options = null)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>addDisplayGroups(array $groups)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>setDisplayGroups(array $groups)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>getDisplayGroup($name)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>getDisplayGroups()</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>removeDisplayGroup($name)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>clearDisplayGroups()</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>setDisplayGroupDecorators(array
                            $decorators)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>addDisplayGroupPrefixPath($prefix,
                            $path)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>setDefaultDisplayGroupClass($class)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>getDefaultDisplayGroupClass($class)</methodname>
                    </para>
                </listitem>
            </itemizedlist>
        </sect3>

        <sect3 id="zend.form.forms.displaygroups.methods">
            <title>Métodos Zend_Form_DisplayGroup</title>

            <para>
                <classname>Zend_Form_DisplayGroup</classname> tiene los
                siguientes métodos, agrupados por tipo: </para>

            <itemizedlist>
                <listitem>
                    <para>Configuración:</para>
                    <itemizedlist>
                        <listitem>
                            <para>
                                <methodname>setOptions(array
                                    $options)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>setConfig(Zend_Config
                                    $config)</methodname>
                            </para>
                        </listitem>
                    </itemizedlist>
                </listitem>

                <listitem>
                    <para>Metadatos:</para>
                    <itemizedlist>
                        <listitem>
                            <para>
                                <methodname>setAttrib($key, $value)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>addAttribs(array
                                    $attribs)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>setAttribs(array
                                    $attribs)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>getAttrib($key)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>getAttribs()</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>removeAttrib($key)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>clearAttribs()</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>setName($name)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>getName()</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>setDescription($value)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>getDescription()</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>setLegend($legend)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>getLegend()</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>setOrder($order)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>getOrder()</methodname>
                            </para>
                        </listitem>
                    </itemizedlist>
                </listitem>

                <listitem>
                    <para>Elementos:</para>
                    <itemizedlist>
                        <listitem>
                            <para>
                                <methodname>createElement($type, $name, array
                                    $options = array())</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>addElement($typeOrElement, $name,
                                    array $options = array())</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>addElements(array
                                    $elements)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>setElements(array
                                    $elements)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>getElement($name)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>getElements()</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>removeElement($name)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>clearElements()</methodname>
                            </para>
                        </listitem>
                    </itemizedlist>
                </listitem>

                <listitem>
                    <para>Cargadores Complemento:</para>
                    <itemizedlist>
                        <listitem>
                            <para>
                                <methodname>setPluginLoader(Zend_Loader_PluginLoader
                                    $loader)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>getPluginLoader()</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>addPrefixPath($prefix,
                                    $path)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>addPrefixPaths(array
                                    $spec)</methodname>
                            </para>
                        </listitem>
                    </itemizedlist>
                </listitem>

                <listitem>
                    <para>Decoratores:</para>
                    <itemizedlist>
                        <listitem>
                            <para>
                                <methodname>addDecorator($decorator, $options =
                                    null)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>addDecorators(array
                                    $decorators)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>setDecorators(array
                                    $decorators)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>getDecorator($name)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>getDecorators()</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>removeDecorator($name)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>clearDecorators()</methodname>
                            </para>
                        </listitem>
                    </itemizedlist>
                </listitem>

                <listitem>
                    <para>Generadores:</para>
                    <itemizedlist>
                        <listitem>
                            <para>
                                <methodname>setView(Zend_View_Interface $view =
                                    null)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>getView()</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>render(Zend_View_Interface $view =
                                    null)</methodname>
                            </para>
                        </listitem>
                    </itemizedlist>
                </listitem>

                <listitem>
                    <para>I18n:</para>
                    <itemizedlist>
                        <listitem>
                            <para>
                                <methodname>setTranslator(Zend_Translate_Adapter
                                    $translator = null)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>getTranslator()</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>setDisableTranslator($flag)</methodname>
                            </para>
                        </listitem>

                        <listitem>
                            <para>
                                <methodname>translatorIsDisabled()</methodname>
                            </para>
                        </listitem>
                    </itemizedlist>
                </listitem>
            </itemizedlist>
        </sect3>
    </sect2>

    <sect2 id="zend.form.forms.subforms">
        <title>Subformularios</title>

        <para>Los Sub formularios sirven para diferentes propósitos:</para>

        <itemizedlist>
            <listitem>
                <para>Crear grupos de elementos lógicos. Dado que los sub
                    formularios son simplemente formularios, se pueden validar
                    subformularios como entidades individuales.</para>
            </listitem>

            <listitem>
                <para>Crear formularios multi-páginas. Dado que los sub
                    formularios son simplemente formularios, se puede deplegar
                    un sub formulario por separado por página, incrementando
                    formularios multi-páginas donde cada formulario tiene su
                    propia validación lógica. Solo una vez que todos los sub
                    formularios se validen, el formulario se consideraría
                    completo.</para>
            </listitem>

            <listitem>
                <para>Agrupaciones de visualización. Como grupos de
                    visualización, los sub formularios, cuando son generados
                    como parte de un formulario más grande, pueden ser usados
                    para agrupar elementos. Sea consciente, de todas maneras,
                    que el objeto formulario principal no tendrá conocimiento de
                    los elementos en un sub formulario.</para>
            </listitem>
        </itemizedlist>

        <para> Un sub formulario puede ser un objeto
                <classname>Zend_Form</classname> o mas originalmente, un objeto
                <classname>Zend_Form_SubForm</classname> . éste último contiene
            decoradores apropiados para la inclusión en un formulario extenso
            (i.e., no se generan adicionales formulario etiquetas
                <acronym>HTML</acronym> , pero si grupos de elementos). Para
            adjuntar un sub formulario, simplemente añádalo al formulario y déle
            un nombre: </para>

        <programlisting language="php"><![CDATA[
$form->addSubForm($subForm, 'subform');
]]></programlisting>

        <para> Se puede recuperar un sub formulario usando ya sea
                <methodname>getSubForm($name)</methodname> o sobrecarga usando
            el nombre del sub formulario: </para>

        <programlisting language="php"><![CDATA[
// Usando getSubForm():
$subForm = $form->getSubForm('subform');

// Usando sobrecarga:
$subForm = $form->subform;
]]></programlisting>

        <para>Los Subformularios son incluidos en la interacción del formulario,
            sin embargo los elementos que lo contienen no lo son</para>

        <sect3 id="zend.form.forms.subforms.global">
            <title>Operaciones Globales</title>

            <para> Como los elementos y los grupos de visualización, existen
                algunas operaciones que pueden afectar a todos los sub
                formularios. A diferencia de los grupos de visualización y los
                elementos, sin embargo, los sub formularios heredan más
                funcionalidad del objeto formulario principal, y la única
                operación real que puede realizarse globalmente es determinar
                decoradores para sub formularios. Para este propósito, existe el
                método <methodname>setSubFormDecorators()</methodname> . En el
                siguiente ejemplo, determinaremos el decorador para todos los
                subformularios que sera un simple campo (el decorador
                FormElements es necesario para asegurar que los elementos son
                iterados): </para>

            <programlisting language="php"><![CDATA[
$form->setSubFormDecorators(array(
    'FormElements',
    'Fieldset'
));
]]></programlisting>
        </sect3>

        <sect3 id="zend.form.forms.subforms.methods">
            <title>Métodos para interactuar con Sub Formularios</title>

            <para>Los siguientes métodos pueden ser usados para interactuar con
                sub formularios:</para>

            <itemizedlist>
                <listitem>
                    <para>
                        <methodname>addSubForm(Zend_Form $form, $name, $order =
                            null)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>addSubForms(array $subForms)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>setSubForms(array $subForms)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>getSubForm($name)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>getSubForms()</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>removeSubForm($name)</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>clearSubForms()</methodname>
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>setSubFormDecorators(array
                            $decorators)</methodname>
                    </para>
                </listitem>
            </itemizedlist>
        </sect3>
    </sect2>

    <sect2 id="zend.form.forms.metadata">
        <title>Metadatos y Atributos</title>

        <para> Mientras la utilidad de un formulario primariamente deriva de los
            elementos que contiene, también pueden contener otros metadatos,
            como un nombre (usado a menudo como ID único en el marcado
                <acronym>HTML</acronym> ); la accion y el método del formulario;
            el número de elementos, grupos y sub formularios que lo contienen; y
            arbitrariamente metadatos (usualmente usados para determinar
            atributos <acronym>HTML</acronym> para la etiqueta del propio
            formulario). </para>

        <para>Se puede determinar y recuperar el nombre del formulario usando el
            accesor nombre:</para>

        <programlisting language="php"><![CDATA[
// Determinar el nombre:
$form->setName('registration');

// Recuperar el nombre:
$name = $form->getName();
]]></programlisting>

        <para>Para determinar la acción (url en el cual se envia el formulario)
            y método (método por el cual debería enviar, ej. 'POST' or 'GET'),
            use los accesores acción y método:</para>

        <programlisting language="php"><![CDATA[
// Determinar la acción y método:
$form->setAction('/user/login')
     ->setMethod('post');
]]></programlisting>

        <para> Se puede también especificar el tipo de codificación del
            fomulario usando el enctype accessors. Zend_Form define dos
            constantes, <constant>Zend_Form::ENCTYPE_URLENCODED</constant> y
                <constant>Zend_Form::ENCTYPE_MULTIPART</constant> ,
            correspondiente a los valores 'application/x-www-form-urlencoded' y
            'multipart/form-data', respectivamente; sin embargo, puede
            configurarlo con cualquier tipo de codificación. </para>

        <programlisting language="php"><![CDATA[
// Determinar la acción, método y enctype:
$form->setAction('/user/login')
     ->setMethod('post')
     ->setEnctype(Zend_Form::ENCTYPE_MULTIPART);
]]></programlisting>

        <note>
            <para>El método, acción y enctype son solo usados internamente para
                generar, y no para algún tipo de validación.</para>
        </note>

        <para>
            <classname>Zend_Form</classname> implementa la interfaz
                <methodname>Countable</methodname> permitiéndole pasarlo como un
            argumento para contar: </para>

        <programlisting language="php"><![CDATA[
$numItems = count($form);
]]></programlisting>

        <para> Determinar metadatos arbitrariamente se realiza a través de los
            accesores 'atribs'. Dado que la sobrecarga en
                <classname>Zend_Form</classname> es usada para acceder
            elementos, grupos de visualización y subformularios, este es el
            único método para acceder a los metadatos. </para>

        <programlisting language="php"><![CDATA[
// Determinando atributos:
$form->setAttrib('class', 'zend-form')
     ->addAttribs(array(
         'id'       => 'registration',
         'onSubmit' => 'validate(this)',
     ));

// Recuperando atributos:
$class = $form->getAttrib('class');
$attribs = $form->getAttribs();

// Removiendo atributos:
$form->removeAttrib('onSubmit');

// Limpiando todos los atributos:
$form->clearAttribs();
]]></programlisting>
    </sect2>

    <sect2 id="zend.form.forms.decorators">
        <title>Decoradores</title>

        <para> Crear el marcado para un formulario es a menudo una tarea que
            consume mucho tiempo, particularmente si se planea reusar el mismo
            marcado para mostrar acciones tales como validación de errores,
            enviar valores, etc. La respuesta de
                <classname>Zend_Form</classname> a este problema es los
                <emphasis>decoradores</emphasis> . </para>

        <para> Los decoradores para objetos <classname>Zend_Form</classname>
            pueden ser usados para generar un formulario. El decorador
            FormElements iterará a través de todos los elementos en un
            formulario -- elementos, grupos de visualización y subformularios --
            y los generará, devolviendo el resultado. Adicionalmente, los
            decoradores pueden ser usados para envolver el contenido o
            anteponerlo o postponerlo. </para>

        <para> Los decoradores por defecto de <classname>Zend_Form</classname>
            son FormElements, HtmlTag (envuelve una lista de definición) y Form;
            el código equivalente para crearlos es como sigue: </para>

        <programlisting language="php"><![CDATA[
$form->setDecorators(array(
    'FormElements',
    array('HtmlTag', array('tag' => 'dl')),
    'Form'
));
]]></programlisting>

        <para>Que crea la salida como sigue:</para>

        <programlisting language="html"><![CDATA[
<form action="/form/action" method="post">
<dl>
...
</dl>
</form>
]]></programlisting>

        <para> Algunos de los atributos se determinan en el objeto formulario
            que será usado como atributos <acronym>HTML</acronym> de la etiqueta
                <methodname>&lt;form&gt;</methodname> . </para>

        <note>
            <title>Decoradores por defecto que no necesitan ser cargados</title>

            <para>Por defecto, el decorador por defecto son cargados durante la
                inicialización del objeto. Puede deshabilitarlo pasando la
                opción 'disableLoadDefaultDecorators' al constructor:</para>

            <programlisting language="php"><![CDATA[
$form = new Zend_Form(array('disableLoadDefaultDecorators' => true));
]]></programlisting>

            <para> Esta opción puede ser combinada con alguna otra opción que
                usted pueda pasar, tanto como opciones de array o en un objeto
                    <classname>Zend_Config</classname>
            </para>
        </note>

        <note>
            <title>Usando multiples decoradores del mismo tipo</title>

            <para> Internamente, <classname>Zend_Form</classname> usa una clase
                decorador como un mecanismo buscador cuando se recuperan
                decoradores. Como resultado, no se pueden registrar multiples
                decoradores del mismo tipo; subsecuentemente los decoradores
                simplemente sobrescribirán esos decoradores que existían antes. </para>

            <para> Para conseguir esto, se pueden usar alias. En vez de pasar un
                decorador o un nombre de decorador como primer argumento a
                    <methodname>addDecorator()</methodname> , pase un array con
                un solo elemento, con el alias apuntando al objeto decorador o
                nombre: </para>

            <programlisting language="php"><![CDATA[
// Alias para 'FooBar':
$form->addDecorator(array('FooBar' => 'HtmlTag'), array('tag' => 'div'));

// y recuperarlo después:
$form = $element->getDecorator('FooBar');
]]></programlisting>

            <para> En los métodos <methodname>addDecorators()</methodname> y
                    <methodname>setDecorators()</methodname> , se necesitará
                pasar la opción 'decorator' en el array representando el
                decorador: </para>

            <programlisting language="php"><![CDATA[
// Añadir dos decoradores 'HtmlTag', poniendo un alias a 'FooBar':
$form->addDecorators(
    array('HtmlTag', array('tag' => 'div')),
    array(
        'decorator' => array('FooBar' => 'HtmlTag'),
        'options' => array('tag' => 'dd')
    ),
);

// y recuperándolo después:
$htmlTag = $form->getDecorator('HtmlTag');
$fooBar  = $form->getDecorator('FooBar');
]]></programlisting>
        </note>

        <para>Puede crear su propio decorador para generar el formulario. Un
            caso de uso común es si sabe el HTML exacto que desea usar; su
            decorador puede crear el mismo HTML y simplemente retornarlo,
            potencialmente usando los decoradores de individuales elementos o
            grupos de visualización.</para>

        <para>Los siguientes métodos puden ser usados para interactuar con
            decoradores:</para>

        <itemizedlist>
            <listitem>
                <para>
                    <methodname>addDecorator($decorator, $options =
                        null)</methodname>
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>addDecorators(array $decorators)</methodname>
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>setDecorators(array $decorators)</methodname>
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>getDecorator($name)</methodname>
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>getDecorators()</methodname>
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>removeDecorator($name)</methodname>
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>clearDecorators()</methodname>
                </para>
            </listitem>
        </itemizedlist>

        <para>
            <classname>Zend_Form</classname> también usa sobrecarga que permite
            generar decoradores específicos. <methodname>__call()</methodname>
            interceptará métodos que lleve con el texto 'render' y use el resto
            del nombre del método para buscar un decorador; si se encuentran,
            serán generados por un <emphasis>solo</emphasis> decorador.
            Cualquier argumento pasado a la llamada del método será usado como
            contenido que pasar al método <methodname>render()</methodname> del
            decorador. Como ejemplo: </para>

        <programlisting language="php"><![CDATA[
// Generar solo los decoradores FormElements:
echo $form->renderFormElements();

// Generar solo el campo decorador, pasando el contenido:
echo $form->renderFieldset("<p>This is fieldset content</p>");
]]></programlisting>

        <para>Si el decorador no existe, una excepción se creará.</para>
    </sect2>

    <sect2 id="zend.form.forms.validation">
        <title>Validación</title>

        <para> Un caso de uso primario para formularios es validar datos
            enviados. <classname>Zend_Form</classname> le permite validar un
            formulario entero de una vez, o una parte de él, asi como también
            automatizar las respuestas de validación para XmlHttpRequests
            (AJAX). Si los datos enviados no son válidos, contiene métodos para
            recuperar los distintos códigos errores y los mensajes de elementos
            y subformularios de validaciones fallidas. </para>

        <para> Para validar un formulario entero, use el método
                <methodname>isValid()</methodname> : </para>

        <programlisting language="php"><![CDATA[
if (!$form->isValid($_POST)) {
    // validación fallida
}
]]></programlisting>

        <para>
            <methodname>isValid()</methodname> validará cada elemento requerido,
            y algún elemento no requerido contenido en la data sometida. </para>

        <para> Algunas veces se necesitará validar sólo un subset del dato; para
            esto use <methodname>isValidPartial($data)</methodname> : </para>

        <programlisting language="php"><![CDATA[
if (!$form->isValidPartial($data)) {
    // validación fallida
}
]]></programlisting>

        <para>
            <methodname>isValidPartial()</methodname> sólo intenta validar
            aquellos elementos en la información para los cuales existen
            similares elementos; si un elemento es no representado en la
            información, es pasado por alto. </para>

        <para> Cuando se validan elementos o grupos de elementos para un
            requeirimiento <acronym>AJAX</acronym> , típicamente se validará un
            subset del formulario, y quiere la respuesta en
                <acronym>JSON</acronym> . <methodname>processAjax()</methodname>
            precisamente realiza eso: </para>

        <programlisting language="php"><![CDATA[
$json = $form->processAjax($data);
]]></programlisting>

        <para> Entonces, puede simplemente enviar la respuesta
                <acronym>JSON</acronym> al cliente. Si el formulario es válido,
            ésta será una respuesta booleana. Si no, será un objeto javascript
            conteniendo pares de clave/mensaje, donde cada 'message' es un array
            de validación de mensajes de error. </para>

        <para> Para los formularios que fallan la validación, se pueden
            recuperar ambos códigos de error y mensajes de error, usando
                <methodname>getErrors()</methodname> y
                <methodname>getMessages()</methodname> , respectivamente: </para>

        <programlisting language="php"><![CDATA[
$codes = $form->getErrors();
$messages = $form->getMessage();
]]></programlisting>

        <note>
            <para> Dado que los mensajes devueltos por
                    <methodname>getMessages()</methodname> son un array de pares
                de errores código/mensaje, <methodname>getErrors()</methodname>
                no es necesario. </para>
        </note>

        <para>Puede recuperar códigos y mensajes de error para elementos
            individuales simplemente pasando el nombre del elemento a cada
            uno:</para>

        <programlisting language="php"><![CDATA[
$codes = $form->getErrors('username');
$messages = $form->getMessages('username');
]]></programlisting>

        <note>
            <para> Nota: Cuando validamos elementos,
                    <classname>Zend_Form</classname> envía un segundo argumento
                a cada método <methodname>isValid()</methodname> del elemento:
                el array de los datos que se están validando. Esto puede ser
                usado por validadores individuales para permitirles utilizar
                otros valores enviados al determinar la validez de los datos. Un
                ejemplo sería un formulario de registro que requiere tanto una
                contraseña como una confirmación de la contraseña; el elemento
                contraseña puede usar la confirmación de la contraseña como
                parte de su validación. </para>
        </note>

        <sect3 id="zend.form.forms.validation.errors">
            <title>Mensajes de error personalizados</title>

            <para>A veces, puede querer especificar uno o más mensajes de error
                en vez de los mensajes de error generados por los validadores
                adjuntos a los elementos. Adicionalmente, a veces puede querer
                marcar el formulario inválido usted mismo. Como 1.6.0, esta
                funcionalidad es posible siguiendo los métodos. At times, you
                may want to specify one or more specific error messages to use
                instead of the error messages generated by the validators
                attached to your elements. Additionally, at times you may want
                to mark the form invalid yourself. As of 1.6.0, this
                functionality is possible via the following methods.</para>

            <itemizedlist>
                <listitem>
                    <para>
                        <methodname>addErrorMessage($message)</methodname> :
                        añade un mensaje de error para desplegar en el
                        formulario los errores de validación. Se debe llamar más
                        de una vez, y los nuevos mensajes son adicionados a la
                        pila. </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>addErrorMessages(array
                            $messages)</methodname> : añade múltiples mensajes
                        de error para desplegar en el formulario los errores de
                        validación </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>setErrorMessages(array
                            $messages)</methodname> : añade multiples mensajes
                        de error para desplegar en el formulario los errores de
                        validación, sobrescribiendo todos los mensajes de error
                        previamente determinados. </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>getErrorMessages()</methodname> : recupera
                        la lista de mensajes de error personalizados que han
                        sido definidos. </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>clearErrorMessages()</methodname> : remueve
                        todos los mensajes de error personalizados que han sido
                        definidos. </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>markAsError()</methodname> : marca el
                        formulario como que la validación ha fallado. </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>addError($message)</methodname> : añade un
                        mensaje a la pila de mensajes de error personalizados y
                        señala al formulario como inválido. </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>addErrors(array $messages)</methodname> :
                        añade muchos mensajes a la pila de mensajes de error
                        personalizados y señala al formulario como inválido.
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>setErrors(array $messages)</methodname> :
                        sobrescribe la pila de mensajes de error personalizada
                        con los mensajes proporcionados y señala el formulario
                        como inválido. </para>
                </listitem>
            </itemizedlist>

            <para>Todos los errores determinados de esta manera pueden ser
                traducidos.</para>
        </sect3>

        <sect3 id="zend.form.forms.validation.values">
            <title>Retrieving Valid Values Only</title>

            <para> There are scenarios when you want to allow your user to work
                on a valid form in several steps. Meanwhile you allow the user
                to save the form with any set of values inbetween. Then if all
                the data is specified you can transfer the model from the
                building or prototying stage to a valid stage. </para>

            <para> You can retrieve all the valid values that match the
                submitted data by calling: </para>

            <programlisting language="php"><![CDATA[
$validValues = $form->getValidValues($_POST);
]]></programlisting>
        </sect3>
    </sect2>

    <sect2 id="zend.form.forms.methods">
        <title>Métodos</title>

        <para> La siguiente lista es la lista completa de métodos disponibles
            para <classname>Zend_Form</classname> , agrupados por tipo: </para>

        <itemizedlist>
            <listitem>
                <para>Configuración y opciones:</para>
                <itemizedlist>
                    <listitem>
                        <para>
                            <methodname>setOptions(array $options)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setConfig(Zend_Config
                                $config)</methodname>
                        </para>
                    </listitem>
                </itemizedlist>
            </listitem>

            <listitem>
                <para>Cargadores de plugins y rutas:</para>
                <itemizedlist>
                    <listitem>
                        <para>
                            <methodname>setPluginLoader(Zend_Loader_PluginLoader_Interface
                                $loader, $type = null)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>getPluginLoader($type =
                                null)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>addPrefixPath($prefix, $path, $type =
                                null) </methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>addPrefixPaths(array $spec)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>addElementPrefixPath($prefix, $path,
                                $type = null)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>addElementPrefixPaths(array
                                $spec)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>addDisplayGroupPrefixPath($prefix,
                                $path)</methodname>
                        </para>
                    </listitem>
                </itemizedlist>
            </listitem>

            <listitem>
                <para>Metadato:</para>
                <itemizedlist>
                    <listitem>
                        <para>
                            <methodname>setAttrib($key, $value)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>addAttribs(array $attribs)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setAttribs(array $attribs)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>getAttrib($key)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>getAttribs()</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>removeAttrib($key)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>clearAttribs()</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setAction($action)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>getAction()</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setMethod($method)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>getMethod()</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setName($name)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>getName()</methodname>
                        </para>
                    </listitem>
                </itemizedlist>
            </listitem>

            <listitem>
                <para>Elementos:</para>
                <itemizedlist>
                    <listitem>
                        <para>
                            <methodname>addElement($element, $name = null,
                                $options = null)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>addElements(array
                                $elements)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setElements(array
                                $elements)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>getElement($name)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>getElements()</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>removeElement($name)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>clearElements()</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setDefaults(array
                                $defaults)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setDefault($name, $value)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>getValue($name)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>getValues()</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>getUnfilteredValue($name)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>getUnfilteredValues()</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setElementFilters(array
                                $filters)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setElementDecorators(array
                                $decorators)</methodname>
                        </para>
                    </listitem>
                </itemizedlist>
            </listitem>

            <listitem>
                <para>Subformularios:</para>
                <itemizedlist>
                    <listitem>
                        <para>
                            <methodname>addSubForm(Zend_Form $form, $name,
                                $order = null)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>addSubForms(array
                                $subForms)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setSubForms(array
                                $subForms)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>getSubForm($name)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>getSubForms()</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>removeSubForm($name)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>clearSubForms()</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setSubFormDecorators(array
                                $decorators)</methodname>
                        </para>
                    </listitem>
                </itemizedlist>
            </listitem>

            <listitem>
                <para>Grupos de Visualización</para>
                <itemizedlist>
                    <listitem>
                        <para>
                            <methodname>addDisplayGroup(array $elements, $name,
                                $options = null)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>addDisplayGroups(array
                                $groups)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setDisplayGroups(array
                                $groups)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>getDisplayGroup($name)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>getDisplayGroups()</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>removeDisplayGroup($name)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>clearDisplayGroups()</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setDisplayGroupDecorators(array
                                $decorators)</methodname>
                        </para>
                    </listitem>
                </itemizedlist>
            </listitem>

            <listitem>
                <para>Validación</para>
                <itemizedlist>
                    <listitem>
                        <para>
                            <methodname>populate(array $values)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>isValid(array $data)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>isValidPartial(array $data)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>processAjax(array $data)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>persistData()</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>getErrors($name = null)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>getMessages($name = null)</methodname>
                        </para>
                    </listitem>
                </itemizedlist>
            </listitem>

            <listitem>
                <para>Generadores:</para>
                <itemizedlist>
                    <listitem>
                        <para>
                            <methodname>setView(Zend_View_Interface $view =
                                null)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>getView()</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>addDecorator($decorator, $options =
                                null)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>addDecorators(array
                                $decorators)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setDecorators(array
                                $decorators)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>getDecorator($name)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>getDecorators()</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>removeDecorator($name)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>clearDecorators()</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>render(Zend_View_Interface $view =
                                null)</methodname>
                        </para>
                    </listitem>
                </itemizedlist>
            </listitem>

            <listitem>
                <para>I18n:</para>
                <itemizedlist>
                    <listitem>
                        <para>
                            <methodname>setTranslator(Zend_Translate_Adapter
                                $translator = null)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>getTranslator()</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setDisableTranslator($flag)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>translatorIsDisabled()</methodname>
                        </para>
                    </listitem>
                </itemizedlist>
            </listitem>
        </itemizedlist>
    </sect2>

    <sect2 id="zend.form.forms.config">
        <title>Configuración</title>

        <para>
            <classname>Zend_Form</classname> es totalmente configurable mediante
                <methodname>setOptions()</methodname> y
                <methodname>setConfig()</methodname> (o pasando opciones o un
            objeto <classname>Zend_Config</classname> al constructor). Usando
            estos métodos, se pueden especificar elementos formulario, grupos de
            visualización, decoradores, y metadatos. </para>

        <para> Como regla general, si 'set' + la clave de opción (option key)
            hacen referencia a métodos <classname>Zend_Form</classname> ,
            entonces el valor proporcionado será pasado al método. Si el
            accessor no existe, se asume que la clave referencia a un atributo,
            y será pasado a <methodname>setAttrib()</methodname> . </para>

        <para>Excepciones a las reglas incluyen lo siguiente:</para>

        <itemizedlist>
            <listitem>
                <para>
                    <methodname>prefixPaths</methodname> será pasado a
                        <methodname>addPrefixPaths()</methodname>
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>elementPrefixPaths</methodname> será pasado a
                        <methodname>addElementPrefixPaths()</methodname>
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>displayGroupPrefixPaths</methodname> será pasado
                    a <methodname>addDisplayGroupPrefixPaths()</methodname>
                </para>
            </listitem>

            <listitem>
                <para>los siguientes establecedores no pueden ser determinado de
                    ésta manera:</para>

                <itemizedlist>
                    <listitem>
                        <para>
                            <methodname>setAttrib (aunque setAttribs
                                *funcionará*)</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setConfig</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setDefault</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setOptions</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setPluginLoader</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setSubForms</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setTranslator</methodname>
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>setView</methodname>
                        </para>
                    </listitem>
                </itemizedlist>
            </listitem>
        </itemizedlist>

        <para>Como un ejemplo, aquí esta un archivo de configuración que pasa la
            configuración por cada tipo de datos configurables:</para>

        <programlisting language="ini"><![CDATA[
[element]
name = "registration"
action = "/user/register"
method = "post"
attribs.class = "zend_form"
attribs.onclick = "validate(this)"

disableTranslator = 0

prefixPath.element.prefix = "My_Element"
prefixPath.element.path = "My/Element/"
elementPrefixPath.validate.prefix = "My_Validate"
elementPrefixPath.validate.path = "My/Validate/"
displayGroupPrefixPath.prefix = "My_Group"
displayGroupPrefixPath.path = "My/Group/"

elements.username.type = "text"
elements.username.options.label = "Username"
elements.username.options.validators.alpha.validator = "Alpha"
elements.username.options.filters.lcase = "StringToLower"
; more elements, of course...

elementFilters.trim = "StringTrim"
;elementDecorators.trim = "StringTrim"

displayGroups.login.elements.username = "username"
displayGroups.login.elements.password = "password"
displayGroupDecorators.elements.decorator = "FormElements"
displayGroupDecorators.fieldset.decorator = "Fieldset"

decorators.elements.decorator = "FormElements"
decorators.fieldset.decorator = "FieldSet"
decorators.fieldset.decorator.options.class = "zend_form"
decorators.form.decorator = "Form"
]]></programlisting>

        <para> El código de arriba fácilmente puede ser abstraído a un
                <acronym>XML</acronym> o un archivo de configuración basado en
            arrays <acronym>PHP</acronym> . </para>
    </sect2>

    <sect2 id="zend.form.forms.custom">
        <title>Formularios personalizados</title>

        <para> Una alternativa a usar los formularios basados en configuraciones
            es realizar una subclase de <classname>Zend_Form</classname> . Esto
            tiene muchos beneficios: </para>

        <itemizedlist>
            <listitem>
                <para>Se puede centrar la prueba de su formulario facilmente
                    para asegurar las validaciones y generar la ejecución
                    esperada.</para>
            </listitem>

            <listitem>
                <para>Control preciso sobre los individuales elementos.</para>
            </listitem>

            <listitem>
                <para>Reutilización del objeto formulario, y mejor portabilidad
                    (no se necesita seguir los archivos de configuración).
                </para>
            </listitem>

            <listitem>
                <para>Implementar funcionalidad personalizada.</para>
            </listitem>
        </itemizedlist>

        <para> El caso mas típico de uso sería el método
                <methodname>init()</methodname> para determinar elementos de
            formulario específicos y de configuración: </para>

        <programlisting language="php"><![CDATA[
class My_Form_Login extends Zend_Form
{
    public function init()
    {
        $username = new Zend_Form_Element_Text('username');
        $username->class = 'formtext';
        $username->setLabel('Username:')
                 ->setDecorators(array(
                     array('ViewHelper',
                           array('helper' => 'formText')),
                     array('Label',
                           array('class' => 'label'))
                 ));

        $password = new Zend_Form_Element_Password('password');
        $password->class = 'formtext';
        $password->setLabel('Username:')
                 ->setDecorators(array(
                     array('ViewHelper',
                           array('helper' => 'formPassword')),
                     array('Label',
                           array('class' => 'label'))
                 ));

        $submit = new Zend_Form_Element_Submit('login');
        $submit->class = 'formsubmit';
        $submit->setValue('Login')
               ->setDecorators(array(
                   array('ViewHelper',
                   array('helper' => 'formSubmit'))
               ));

        $this->addElements(array(
            $username,
            $password,
            $submit
        ));

        $this->setDecorators(array(
            'FormElements',
            'Fieldset',
            'Form'
        ));
    }
}
]]></programlisting>

        <para>Este formulario puede ser instanciado simplemente así:</para>

        <programlisting language="php"><![CDATA[
$form = new My_Form_Login();
]]></programlisting>

        <para>y toda la funcionalidad está instalada y lista; no se necesitan
            archivos de configuración. (Note que este ejemplo esta simplificado,
            no contiene validadores o filtros para los elementos.)</para>

        <para> Otra razón común para la extension es definir un conjunto de
            decoradores por defecto. Puede hacerlo sobreescribiendo el método
                <methodname>loadDefaultDecorators()</methodname> : </para>

        <programlisting language="php"><![CDATA[
class My_Form_Login extends Zend_Form
{
    public function loadDefaultDecorators()
    {
        $this->setDecorators(array(
            'FormElements',
            'Fieldset',
            'Form'
        ));
    }
}
]]></programlisting>
    </sect2>
</sect1>
