<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 20115 -->
    <!-- Reviewed: no -->
<sect1 id="zend.form.elements">
    <title>Creando elementos de formulario usando Zend_Form_Element</title>

    <para> Un formulario esta compuesto de elementos, que normalmente
        corresponden al elemento HTML input.
            <classname>Zend_Form_Element</classname> encapsula elementos de
        formulario individualmente, con las siguientes áreas de responsabilidad: </para>

    <itemizedlist>
        <listitem>
            <para>validación (¿los datos enviados son válidos?)</para>

            <itemizedlist>
                <listitem>
                    <para>captura de códigos y mensajes de error</para>
                </listitem>
            </itemizedlist>
        </listitem>

        <listitem>
            <para>filtrado (¿cómo es escapado y normalizado el elemento para su
                validación y/o salida?</para>
        </listitem>

        <listitem>
            <para>generación (¿cómo es mostrado el elemento?)</para>
        </listitem>

        <listitem>
            <para>metadatos y atributos (¿qué información amplía la definición
                del elemento?)</para>
        </listitem>
    </itemizedlist>

    <para> La clase base, <classname>Zend_Form_Element</classname> , funciona
        por defecto para varios casos, pero es mejor extender la clase para
        elementos con fines especiales de uso común. Adicionalmente, Zend
        Framework contiene un número de elementos <acronym>XHTML</acronym>
        estándar; puede leer de ellos <link linkend="zend.form.standardElements"
            >en el capítulo Elementos Estándares</link>
    </para>

    <sect2 id="zend.form.elements.loaders">
        <title>Cargadores de Plugin</title>

        <para>
            <classname>Zend_Form_Element</classname> hace uso de <link
                linkend="zend.loader.pluginloader"
                >Zend_Loader_PluginLoader</link> para permitir a los
            desarrolladores especificar ubicaciones de validadores, filtros y
            decoradores alternos. Cada uno tiene su propio cargador de plugin
            asociado a él y métodos de acceso generales usados para su
            recuperación y modificación. </para>

        <para>Los siguientes tipos de cargadores son usados con los varios
            métodos del cargador de plugin: 'validate', 'filter', y 'decorator'.
            Los nombres son sensibles a mayúsculas y minúsculas.</para>

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

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

            <listitem>
                <para>
                    <methodname>getPluginLoader()</methodname> : obtiene el
                    cargador de plugin asociado con <varname></varname> .
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>addPrefixPath($prefix, $path, $type =
                        null)</methodname> : agrega una asociación prefijo/ruta
                    para el cargador especificado por <varname>$type</varname> .
                    Si <varname>$type</varname> es <constant>NULL</constant>, se intentará agregar la
                    ruta a todos los cargadores, añadiendo el prefijo a cada
                    "_Validate", "_Filter" y "_Decorator"; y agregandole
                    "Validate/", "Filter/" y "Decorator/" a la ruta. Si tiene
                    todas sus clases extras para elementos de formulario dentro
                    de una jerarquía común, este método es conveniente para
                    establecer el prefijo para todas ellas. </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>addPrefixPaths(array $spec)</methodname> : le
                    permite añadir varias rutas de una sola vez a uno o más
                    cargadores de plugin. Se espera cada elemento de la matriz
                    sea un array con claves 'path', 'prefix', y 'type'. </para>
            </listitem>
        </itemizedlist>

        <para>Validadores, filtros y decoradores personalizados son una manera
            simple de compartir funcionalidad entre formularios y encapsular
            funcionalidad personalizada.</para>

        <example id="zend.form.elements.loaders.customLabel">
            <title>Etiqueta personalizada</title>

            <para>Un uso común de los plugins es proveer reemplazos para las
                clases estándares. Por ejemplo, si desea proveer una
                implementación diferente del decorador 'Label' -- por ejemplo,
                para añadir siempre dos puntos -- puede crear su propio
                decorador 'Label' con su propio prefijo de clase, y entonces
                añadirlo a su prefijo de ruta.</para>

            <para>Comencemos con un decorador de etiqueta personalizado. Le
                daremos el prefijo "My_Decorator", y la clase estará en el
                archivo "My/Decorator/Label.php".</para>

            <programlisting language="php"><![CDATA[
class My_Decorator_Label extends Zend_Form_Decorator_Abstract
{
    protected $_placement = 'PREPEND';

    public function render($content)
    {
        if (null === ($element = $this->getElement())) {
            return $content;
        }
        if (!method_exists($element, 'getLabel')) {
            return $content;
        }

        $label = $element->getLabel() . ':';

        if (null === ($view = $element->getView())) {
            return $this->renderLabel($content, $label);
        }

        $label = $view->formLabel($element->getName(), $label);

        return $this->renderLabel($content, $label);
    }

    public function renderLabel($content, $label)
    {
        $placement = $this->getPlacement();
        $separator = $this->getSeparator();

        switch ($placement) {
            case 'APPEND':
                return $content . $separator . $label;
            case 'PREPEND':
            default:
                return $label . $separator . $content;
        }
    }
}
]]></programlisting>

            <para>Ahora diremos al elemento que use esta ruta cuando busque por
                decoradores:</para>

            <programlisting language="php"><![CDATA[
$element->addPrefixPath('My_Decorator', 'My/Decorator/', 'decorator');
]]></programlisting>

            <para>Alternativamente, podemos hacerlo en el formulario para
                asegurar que todos los decoradores usen esta ruta:</para>

            <programlisting language="php"><![CDATA[
$form->addElementPrefixPath('My_Decorator', 'My/Decorator/', 'decorator');
]]></programlisting>

            <para>Con esta ruta añadida, cuando agregue un decorador, la ruta
                'My/Decorator' será consultada primero en búsqueda de la
                existencia del decorador en este lugar. Como resultado,
                'My_Decorator_Label' ahora será utilizado cuando el decorador
                'Label' sea requerido.</para>
        </example>
    </sect2>

    <sect2 id="zend.form.elements.filters">
        <title>Filters</title>

        <para> A menudo es útil y/o necesario realizar alguna normalización en
            la entrada antes de la validación – por ejemplo, puede querer
            eliminar todo el <acronym>HTML</acronym> , pero realizar las
            validaciones sobre lo restante para asegurarse que el envío es
            válido. O puede eliminar los espacios en blanco al inicio o fin de
            la entrada para asegurarse de que un validador StringLenth (longitud
            de la cadena) no regrese un positivo falso. Estas operaciones pueden
            realizarse usando <classname>Zend_Filter</classname> , y
                <classname>Zend_Form_Element</classname> que soportan cadenas de
            filtros, permitiéndole especificar múltiples filtros secuenciales a
            utilizar. El filtrado sucede tanto en la validación como cuando
            recupera el valor del elemento vía
                <methodname>getValue()</methodname> : </para>

        <programlisting language="php"><![CDATA[
$filtered = $element->getValue();

]]></programlisting>

        <para>Los filtros pueden ser agregados a la pila de dos maneras:</para>

        <itemizedlist>
            <listitem>
                <para>pasándolo en una instancia de filtro específica</para>
            </listitem>

            <listitem>
                <para>proveyendo un nombre de filtro – el correspondiente nombre
                    corto o completo de la clase</para>
            </listitem>
        </itemizedlist>

        <para>Veamos algunos ejemplos:</para>

        <programlisting language="php"><![CDATA[
// Instancia específica del filtro
$element->addFilter(new Zend_Filter_Alnum());

// El correspondiente nombre completo de la clase:
$element->addFilter('Zend_Filter_Alnum');

// Nombre corto del filtro:
$element->addFilter('Alnum');
$element->addFilter('alnum');
]]></programlisting>

        <para>Los nombres cortos son típicamente el nombre del filtro sin el
            prefijo. En el caso predeterminado, esto se refiere a sin el prefijo
            'Zend_Filter_'. Además, la primera letra no necesita estar en
            mayúscula.</para>

        <note>
            <title>Usando clases de filtros personalizados</title>

            <para> Si tiene su propio conjunto de clases de filtro, puede
                informarle de ellas a <classname>Zend_Form_Element</classname>
                usando <methodname>addPrefixPath()</methodname> . Por ejemplo,
                si tiene filtros con el prefijo 'My_Filter', puede indicárselo a
                    <classname>Zend_Form_Element</classname> de la siguiente
                manera: </para>

            <programlisting language="php"><![CDATA[
$element->addPrefixPath('My_Filter', 'My/Filter/', 'filter');
]]></programlisting>

            <para>(Recuerde que el tercer argumento indica el cargador de plugin
                sobre el cual ha de ejecutarse la acción.)</para>
        </note>

        <para> Si en algún momento necesita un valor no filtrado, use el método
                <methodname>getUnfilteredValue()</methodname> : </para>

        <programlisting language="php"><![CDATA[
$unfiltered = $element->getUnfilteredValue();
]]></programlisting>

        <para> Para mayor información sobre filtros, vea la <link
                linkend="zend.filter.introduction">documentación de
                Zend_Filter</link> . </para>

        <para>Métodos asociados con filtros incluyen:</para>

        <itemizedlist>
            <listitem>
                <para>
                    <methodname>addFilter($nameOfFilter, array $options =
                        null)</methodname>
                </para>
            </listitem>

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

            <listitem>
                <para>
                    <methodname>setFilters(array $filters)</methodname>
                    (sobreescribe todos los filtros) </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>getFilter($name)</methodname> (recupera un
                    objeto filtro por su nombre) </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>getFilters()</methodname> (recupera todos los
                    filtros) </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>removeFilter($name)</methodname> (elimina un
                    filtro por su nombre) </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>clearFilters()</methodname> (elimina todos los
                    filtros) </para>
            </listitem>
        </itemizedlist>
    </sect2>

    <sect2 id="zend.form.elements.validators">
        <title>Validadores</title>

        <para> Si sigue el mantra de seguridad "filtrar la entrada, escapar la
            salida" querrá validar ("filtrar la entrada") los datos de los
            formularios. En <classname>Zend_Form</classname> cada elemento
            contiene su propia cadena de validadores, consistente en validadores
                <methodname>Zend_Validate_*</methodname> . </para>

        <para>Los validadores pueden ser agregados de dos maneras:</para>

        <itemizedlist>
            <listitem>
                <para>pasándolo en una instancia de validador específica </para>
            </listitem>

            <listitem>
                <para>proveyendo un nombre de validador – el correspondiente
                    nombre corto o completo de clase</para>
            </listitem>
        </itemizedlist>

        <para>Veamos algunos ejemplos:</para>

        <programlisting language="php"><![CDATA[
// Instancia específica del validador:
$element->addValidator(new Zend_Validate_Alnum());

// El correspondiente nombre completo de la clase:
$element->addValidator('Zend_Validate_Alnum');

// Nombre corto del validador:
$element->addValidator('Alnum');
$element->addValidator('alnum');
]]></programlisting>

        <para>Los nombres cortos son típicamente el nombre del validador sin el
            prefijo. En el caso predeterminado, esto se refiere a sin el prefijo
            'Zend_Validate_'. Además, la primera letra no necesita estar en
            mayúscula.</para>

        <note>
            <title>Usando clases de validación personalizadas</title>

            <para> Si tiene su propio conjunto de clases de validación, puede
                informarle de ellas a <classname>Zend_Form_Element</classname>
                usando <methodname>addPrefixPath()</methodname> . Por ejemplo,
                si tiene validadores con el prefijo 'My_Validator', puede
                indicárselo a <classname>Zend_Form_Element</classname> de la
                siguiente manera: </para>

            <programlisting language="php"><![CDATA[
$element->addPrefixPath('My_Validator', 'My/Validator/', 'validate');
]]></programlisting>

            <para>(Recuerde que el tercer argumento indica el cargador de plugin
                sobre el cual ha de ejecutarse la acción.)</para>
        </note>

        <para> Si el fallo de un validador debe evitar validaciones posteriores,
            pase el boleano <constant>TRUE</constant> como segundo parámetro: </para>

        <programlisting language="php"><![CDATA[
$element->addValidator('alnum', true);
]]></programlisting>

        <para> Si está usando la cadena nombre para añadir el validador, y la
            clase del validador acepta argumentos para su constructor, puede
            pasarlos a el tercer parámetro de
                <methodname>addValidator()</methodname> como un array: </para>

        <programlisting language="php"><![CDATA[
$element->addValidator('StringLength', false, array(6, 20));
]]></programlisting>

        <para> Los argumentos pasados de esta manera deben estar en el orden en
            el cual son definidos en el constructor. El ejemplo de arriba
            instanciará la clase
                <classname>Zend_Validate_StringLenth</classname> con los
            parámetros <varname>$min</varname> y <varname>$max</varname> : </para>

        <programlisting language="php"><![CDATA[
$validator = new Zend_Validate_StringLength(6, 20);
]]></programlisting>

        <note>
            <title>Estipulando mensajes de error de validación
                personalizados</title>

            <para> Algunos desarrolladores querrán estipular mensajes de error
                personalizados para un validador. El argumento
                    <varname>$options</varname> de
                    <methodname>Zend_Form_Element::addValidator()</methodname>
                le permite hacerlo proporcionando la clave 'messages' y
                estableciendolos en un array de pares clave/valor para
                especificar las plantillas de mensaje. Necesitará conocer los
                códigos de error de los diferentes tipos de error de un
                validador en particular. </para>

            <para> Una opción mejor es usar
                    <classname>Zend_Translate_Adapter</classname> con su
                formulario. Los códigos de error son automáticamente pasados al
                adaptador por el decorador Errors por defecto; puede especificar
                su propias cadenas de mensaje de error mediante la creación de
                traducciones para los varios códigos de error de sus
                validadores. </para>
        </note>

        <para> Puede también establecer varios validadores a la vez, usando
                <methodname>addValidators()</methodname> . Su uso básico es
            pasar una matriz de arrays, donde cada array contenga de 1 a 3
            valores, correspondientes al constructor de
                <methodname>addValidator()</methodname> : </para>

        <programlisting language="php"><![CDATA[
$element->addValidators(array(
    array('NotEmpty', true),
    array('alnum'),
    array('stringLength', false, array(6, 20)),
));
]]></programlisting>

        <para>Si quiere ser más detallado o explícito, puede utilizar las claves
            'validator', 'breakChainOnFailure', y 'options' en el array:</para>

        <programlisting language="php"><![CDATA[
$element->addValidators(array(
    array(
        'validator'           => 'NotEmpty',
        'breakChainOnFailure' => true),
    array('validator' => 'alnum'),
    array(
        'validator' => 'stringLength',
        'options'   => array(6, 20)),
));
]]></programlisting>

        <para>Este uso es bueno para ilustrar cómo puede configurar validadores
            en un archivo de configuración:</para>

        <programlisting language="ini"><![CDATA[
element.validators.notempty.validator = "NotEmpty"
element.validators.notempty.breakChainOnFailure = true
element.validators.alnum.validator = "Alnum"
element.validators.strlen.validator = "StringLength"
element.validators.strlen.options.min = 6
element.validators.strlen.options.max = 20
]]></programlisting>

        <para>Note que cada elemento tiene una clave, la necesite o no; esta es
            una limitación del uso de archivos de configuración -- pero también
            ayuda a hacer más explicito el para qué son usados los argumentos.
            Sólo recuerde que cualesquiera opciones del validador deben ser
            especificadas en orden.</para>

        <para> Para validar un elemento, pase el valor a
                <methodname>isValid()</methodname> : </para>

        <programlisting language="php"><![CDATA[
if ($element->isValid($value)) {
    // válido
} else {
    // no válido
}
]]></programlisting>

        <note>
            <title>Validación operando en valores filtrados</title>

            <para>
                <methodname>Zend_Form_Element::isValid()</methodname> > siempre
                filtra los valores antes de la validación a través de la cadena
                de filtros. Vea <link linkend="zend.form.elements.filters">la
                    sección de filtros</link> para más información. </para>
        </note>

        <note>
            <title>Contexto de validación</title>

            <para>
                <methodname>Zend_Form_Element::isValid()</methodname> > soporta
                un argumento adicional, <varname>$context</varname> .
                    <methodname>Zend_Form::isValid()</methodname> pasa todo el
                conjunto de datos procesados a <varname>$context</varname>
                cuando valida un formulario, y
                    <methodname>Zend_Form_Element::isValid()</methodname> >, a
                su vez, lo pasa a cada validador. Esto significa que puede
                escribir validadores que son conscientes de los datos pasados a
                otros elementos del formulario. Como ejemplo, considere un
                formulario de registro estándar que tiene campos para la
                contraseña y la confirmación de la contraseña; una validación
                sería que los dos campos coincidan. Este validador puede tener
                un aspecto como el siguiente: </para>

            <programlisting language="php"><![CDATA[
class My_Validate_PasswordConfirmation extends Zend_Validate_Abstract
{
    const NOT_MATCH = 'notMatch';

    protected $_messageTemplates = array(
        self::NOT_MATCH => 'Password confirmation does not match'
    );

    public function isValid($value, $context = null)
    {
        $value = (string) $value;
        $this->_setValue($value);

        if (is_array($context)) {
            if (isset($context['password_confirm'])
                && ($value == $context['password_confirm']))
            {
                return true;
            }
        } elseif (is_string($context) && ($value == $context)) {
            return true;
        }

        $this->_error(self::NOT_MATCH);
        return false;
    }
}
]]></programlisting>
        </note>

        <para> Los validadores son procesados en orden. Cada validador es
            procesado, a menos que un validador creado con un valor true para
                <methodname>breakChainOnFailure</methodname> falle su
            validación. Asegúrese de especificar sus validadores en un orden
            razonable. </para>

        <para>Después de una validación fallida, puede recuperar los códigos y
            mensajes de error de la cadena del validador:</para>

        <programlisting language="php"><![CDATA[
$errors   = $element->getErrors();
$messages = $element->getMessages();
]]></programlisting>

        <para>(Nota: los mensajes de error retornados son un array asociativo de
            pares código / mensaje de error.)</para>

        <para> En adición a los validadores, puede especificar que un elemento
            es necesario, usando <methodname>setRequired(true)</methodname> .
            Por defecto, esta bandera es <constant>FALSE</constant> , lo que
            significa que pasará su cadena de validadores si ningún valor es
            pasado a <methodname>isValid()</methodname> . Puede modificar este
            comportamiento en un número de maneras: </para>

        <itemizedlist>
            <listitem>
                <para> Por defecto, cuando un elemento es requerido, una
                    bandera, 'allowEmpty', también es true. Esto quiere decir
                    que si un valor empty es evaluado pasándolo a
                        <methodname>isValid()</methodname> , los validadores
                    serán saltados. Puede intercalar esta bandera usando el
                    método de acceso
                        <methodname>setAllowEmpty($flag)</methodname> ; cuando
                    la bandera es false, si un valor es pasado, los validadores
                    seguirán ejecutándose. </para>
            </listitem>

            <listitem>
                <para> Por defecto, si un elemento es requerido, pero no
                    contiene un validador 'NotEmpty',
                        <methodname>isValid()</methodname> añadirá uno en la
                    cima de la pila, con la bandera
                        <methodname>breakChainOnFailure</methodname>
                    establecido. Esto hace que la bandera requerida tenga un
                    significado semántico: si ningún valor es pasado,
                    inmediatamente invalidamos el envío y se le notifica al
                    usuario, e impedimos que otros validadores se ejecuten en lo
                    que ya sabemos son datos inválidos. </para>

                <para> Si no quiere este comportamiento, puede desactivarlo
                    pasando un valor false a
                        <methodname>setAutoInsertNotEmptyValidator($flag)</methodname>
                    ; esto prevendrá a <methodname>isValid()</methodname> de
                    colocar un validador 'NotEmpty' en la cadena de
                    validaciones. </para>
            </listitem>
        </itemizedlist>

        <para> Para mayor información sobre validadores, vea la <link
                linkend="zend.validate.introduction">documentación de
                Zend_Validate</link> . </para>

        <note>
            <title>Usando Zend_Form_Elements como validador de propósito
                general</title>

            <para>
                <classname>Zend_Form_Element</classname> implementa
                    <classname>Zend_Validate_Interface</classname> ,
                significando un elemento puede también usarse como un validador
                en otro, cadenas de validación no relacionadas al formulario.
            </para>
        </note>

        <para>Métodos asociados con validación incluyen:</para>

        <itemizedlist>
            <listitem>
                <para>
                    <methodname>setRequired($flag)</methodname> y
                        <methodname>isRequired()</methodname> permiten
                    establecer y recuperar el estado de la bandera 'required'.
                    Cuando se le asigna un booleano <constant>TRUE</constant> ,
                    esta bandera requiere que el elemento esté presente en la
                    información procesada por <classname>Zend_Form</classname> .
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>setAllowEmpty($flag)</methodname> y
                        <methodname>getAllowEmpty()</methodname> permiten
                    modificar el comportamiento de elementos opcionales (p.e.,
                    elementos donde la bandera required es <constant>FALSE</constant>). Cuando la
                    bandera 'allow empty' es <constant>TRUE</constant> , valores
                    vacíos no pasarán la cadena de validadores. </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>setAutoInsertNotEmptyValidator($flag)</methodname>
                    permite especificar si realmente un validador 'NotEmpty'
                    será añadido el inicio de la cadena de validaciones cuando
                    un elemento es requerido. Por defecto, esta bandera es
                        <constant>TRUE</constant> . </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>addValidator($nameOrValidator,
                        $breakChainOnFailure = false, array $options =
                        null)</methodname>
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>addValidators(array $validators)</methodname>
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>setValidators(array $validators)</methodname>
                    (sobreescribe todos los validadores) </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>getValidator($name)</methodname> (recupera un
                    objeto validador por nombre) </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>getValidators()</methodname> (recupera todos los
                    validadores) </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>removeValidator($name)</methodname> (elimina un
                    validador por nombre) </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>clearValidators()</methodname> (elimina todos
                    los validadores) </para>
            </listitem>
        </itemizedlist>

        <sect3 id="zend.form.elements.validators.errors">
            <title>Errores de mensaje personalizados</title>

            <para>Alguna veces, querrá especificar uno o más mensajes de error
                para usarlos en lugar de los mensajes de error generados por los
                validadores adjuntos a los elementos. Adicionalmente, algunas
                veces usted mismo querrá marcar al elemento como inválido. A
                partir de 1.6.0, esta funcionalidad es posible vía los
                siguientes métodos.</para>

            <itemizedlist>
                <listitem>
                    <para>
                        <methodname>addErrorMessage($message)</methodname> :
                        añade un mensaje de error para mostrarlos en forma de
                        errores de validación. Puede llamarlo más de una vez, y
                        los nuevos mensajes nuevos son añadidos a la pila.
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>addErrorMessages(array
                            $messages)</methodname> : añade múltiples mensajes
                        de error para mostrarlos en forma de errores de
                        validación. </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>setErrorMessages(array
                            $messages)</methodname> : añade múltiples mensajes
                        de error para mostrarlos en forma de errores de
                        validación, sobreescribiendo todos los mensajes de error
                        previamente establecidos. </para>
                </listitem>

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

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

                <listitem>
                    <para>
                        <methodname>markAsError()</methodname> : marca al
                        elemento como que falló la validación. </para>
                </listitem>

                <listitem>
                    <para>
                        <methodname>hasErrors()</methodname> : determina si el
                        elemento ha fallado la validación o ha sido marcado como
                        inválido. </para>
                </listitem>

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

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

                <listitem>
                    <para>
                        <methodname>setErrors(array $messages)</methodname> :
                        sobreescribe el mensaje de error personalizado en la
                        pila con los mensajes previstos y marca al elemento como
                        inválido. </para>
                </listitem>
            </itemizedlist>

            <para>Todos los errores establecidos de este modo pueden ser
                traducidos. Adicionalmente, puede insertar el marcador "%value%"
                para representar el valor del elemento; este valor actual del
                elemento será sustituido cuando el mensaje de error sea
                recuperado.</para>
        </sect3>
    </sect2>

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

        <para> Una dolencia particular para muchos desarrolladores web es la
            creación del <acronym>XHTML</acronym> para formularios por ellos
            mismos. Para cada elemento, el desarrollador necesita crear la
            marcación para el elemento mismo, comúnmente una etiqueta (label),
            y, si son amables con sus usuarios, la marcación para mostrar
            mensajes de errores de validación. Cuanto más elementos en una
            página, menos trivial se convierte esta tarea. </para>

        <para>
            <classname>Zend_Form_Element</classname> intenta resolver este
            problema mediante el uso de "decoradores". Los decoradores son
            clases simples que tienen métodos de acceso al elemento y métodos
            para generar el contenido. Para obtener mayor información sobre cómo
            trabajan los decoradores, consulte por favor la sección sobre <link
                linkend="zend.form.decorators">Zend_Form_Decorator</link> . </para>

        <para> Los decoradores usados por defecto por
                <classname>Zend_Form_Element</classname> son: </para>

        <itemizedlist>
            <listitem>
                <para>
                    <emphasis>ViewHelper</emphasis> : especifica un view helper
                    que usar para general el elemento. El atributo 'helper' del
                    elemento puede usarse para especificar qué auxiliar vista
                    usar. Por defecto, <classname>Zend_Form_Element</classname>
                    especifica el auxiliar vista 'formText', pero cada subclase
                    especifica diferentes auxiliares. </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>Errors</emphasis> : añade mensajes de error al
                    elemento usando
                        <classname>Zend_View_Helper_FormErrors</classname> . Si
                    no está presente, no se añade nada. </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>Description</emphasis>: añade la descripción del
                    elemento. Si no está presente, no se añade nada. Por
                    defecto, la descripción es generada dentro de una etiqueta
                    &lt;p&gt; con un class 'description'. </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>HtmlTag</emphasis>: envuelve el elemento y los
                    errores en una etiqueta HTML &lt;dd&gt;. </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>Label</emphasis> : añade al comienzo una etiqueta
                    al elemento usando
                        <classname>Zend_View_Helper_FormLabel</classname>, y
                    envolviéndola en una etiqueta &lt;dt&gt;. Si ninguna
                    etiqueta es provista, solo la etiqueta de la definición es
                    generada. </para>
            </listitem>
        </itemizedlist>

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

            <para>Por defecto, los decoradores por defecto son cargados durante
                la inicialización del objeto. Puede deshabilitar esto pasando la
                opción 'disableLoadDefaultDecorators' al constructor:</para>

            <programlisting language="php"><![CDATA[
$element = new Zend_Form_Element('foo',
                                 array('disableLoadDefaultDecorators' =>
                                      true)
                                );
]]></programlisting>

            <para> Esta opción puede ser combinada junto con cualquier otra
                opción que pase, ya sea como un array de opciones o en un objeto
                    <classname>Zend_Config</classname> . </para>
        </note>

        <para>Ya que el orden en el cual los decoradores son registrados importa
            -- el primer decorador registrado es ejecutado primero -- necesitará
            estar seguro de registrar sus decoradores en el orden apropiado, o
            asegurarse de que estableció las opciones de colocación en el modo
            apropiado. Por dar un ejemplo, aquí esta el código que registran los
            decoradores por defecto:</para>

        <programlisting language="php"><![CDATA[
$this->addDecorators(array(
    array('ViewHelper'),
    array('Errors'),
    array('Description', array('tag' => 'p', 'class' => 'description')),
    array('HtmlTag', array('tag' => 'dd')),
    array('Label', array('tag' => 'dt')),
));
]]></programlisting>

        <para>El contenido inicial es creado por el decorador 'ViewHelper', que
            crea el propio elemento. En seguida, el decorador 'Errors' consulta
            los mensajes de error del elemento, y, si hay alguno presente, los
            pasa al auxiliar vista 'FormErrors' para mostrarlos. Si una
            descripción está presente, el decorador 'Description' añadirá un
            párrafo con class 'description' conteniendo el texto descriptivo
            para el contenido agregado. El siguiente decorador, 'HtmlTag',
            envuelve al elemento, los errores, y la descripción en una etiqueta
            HTML &lt;dd&gt;. Finalmente, el último decorador, 'label',
            recupera la etiqueta del elemento y la pasa al auxiliar vista
            'FormLabel', envolviéndolo en una etiqueta &lt;dt&gt;; por
            default el valor es añadido al inicio del contenido. El resultado de
            la salida básicamente se ve así:</para>

        <programlisting language="html"><![CDATA[
<dt><label for="foo" class="optional">Foo</label></dt>
<dd>
    <input type="text" name="foo" id="foo" value="123" />
    <ul class="errors">
        <li>"123" is not an alphanumeric value</li>
    </ul>
    <p class="description">
        This is some descriptive text regarding the element.
    </p>
</dd>
]]></programlisting>

        <para> Para más información sobre decoradores, lea la <link
                linkend="zend.form.decorators"> sección de
                Zend_Form_Decorator</link> . </para>

        <note>
            <title>Usando múltiples decoradores al mismo tiempo</title>

            <para> Internamente, <classname>Zend_Form_Element</classname>
                utiliza una clase decorador como mecanismo de búsqueda para la
                recuperación de decoradores. Como resultado, no puede registrar
                múltiples decoradores del mismo tipo; decoradores subsecuentes
                simplemente sobreescribirán aquellos que ya existían. </para>

            <para> Para evitar esto, puede usar <emphasis>alias</emphasis> . En
                lugar de pasar un decorador o nombre de decorador como primer
                argumento a <methodname>addDecorator()</methodname> , pase una
                matriz con un solo elemento, con el alias apuntando al nombre o
                objeto decorador: </para>

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

// Y recuperandolo posteriormente:
$decorator = $element->getDecorator('FooBar');
]]></programlisting>

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

            <programlisting language="php"><![CDATA[
// Y dos decoradores 'HtmlTag', 'FooBar' como alias:
$element->addDecorators(
    array('HtmlTag', array('tag' => 'div')),
    array(
        'decorator' => array('FooBar' => 'HtmlTag'),
        'options' => array('tag' => 'dd')
    ),
);

// Y recuperándolos posteriormente:
$htmlTag = $element->getDecorator('HtmlTag');
$fooBar  = $element->getDecorator('FooBar');
]]></programlisting>
        </note>

        <para>Métodos asociados con decoradores incluyen:</para>

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

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

            <listitem>
                <para>
                    <methodname>setDecorators(array $decorators)</methodname>
                    (sobreescribe todos los decoradores) </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>getDecorator($name)</methodname> (recupera un
                    objeto decorador por su nombre) </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>getDecorators()</methodname> (recupera todos los
                    decoradores) </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>removeDecorator($name)</methodname> (elimina un
                    decorador por su nombre) </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>clearDecorators()</methodname> (elimina todos
                    los decoradores) </para>
            </listitem>
        </itemizedlist>

        <para>
            <classname>Zend_Form_Element</classname> también utiliza la
            sobrecarga para permitir generar decoradores específicos.
                <methodname>__call()</methodname> interceptará métodos que
            comiencen con el texto 'render' y utilizará el resto del nombre del
            método para buscar un decorador; si se encuentra, entonces será
            generado <emphasis>sólo ese</emphasis> decorador. Cualquier
            argumento pasado al llamado del método será usado como contenido
            para pasar al método <methodname>render()</methodname> del
            decorador. Como ejemplo: </para>

        <programlisting language="php"><![CDATA[
// Genera solo el decorador ViewHelper:
echo $element->renderViewHelper();

// Genera solo el decorador HtmlTag, pasándole contenido:
echo $element->renderHtmlTag("This is the html tag content");
]]></programlisting>

        <para>Si el decorador no existe, una excepción es lanzada.</para>
    </sect2>

    <sect2 id="zend.form.elements.metadata">
        <title>Metadatos y atributos</title>

        <para>
            <classname>Zend_Form_Element</classname> manipula una variedad de
            atributos y medatados del elemento. Atributos básicos incluyen: </para>

        <itemizedlist>
            <listitem>
                <para>
                    <emphasis>name</emphasis> : el nombre del elemento. Emplea
                    los métodos de acceso <methodname>setName()</methodname> y
                        <methodname>getName()</methodname> . </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>label</emphasis> : la etiqueta del elemento.
                    Emplea los métodos de acceso
                        <methodname>setLabel()</methodname> y
                        <methodname>getLabel()</methodname> . </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>order</emphasis> : el índice en el cual los
                    elementos deben ir mostrándose en el formulario. Emplea los
                    métodos de acceso <methodname>setOrder()</methodname> y
                        <methodname>getOrder()</methodname> . </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>value</emphasis> : El valor del elemento actual.
                    Emplea los métodos de acceso
                        <methodname>setValue()</methodname> y
                        <methodname>getValue()</methodname> . </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>description</emphasis> : una descripción del
                    elemento; a menudo utilizada para proveer un tooltip o ayuda
                    contextual con javascript describiendo el propósito del
                    elemento. Emplea los métodos de acceso
                        <methodname>setDescription()</methodname> y
                        <methodname>getDescription()</methodname> . </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>required</emphasis> : bandera que indica si un
                    elemento es requerido o no cuando se efectúa la validación
                    del formulario. Emplea los métodos de acceso
                        <methodname>setRequired()</methodname> y
                        <methodname>getRequired()</methodname> . Esta bandera es
                        <constant>FALSE</constant> por defecto. </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>allowEmpty</emphasis> : bandera indicando si un
                    elemento no-requerido (opcional) debe intentar validar o no
                    valores vacíos. Cuando es <constant>TRUE</constant> , y la
                    bandera required es <constant>FALSE</constant> , valores
                    vacíos no pasarán la cadena de validación, y se supone
                    verdadero. Emplea los métodos de acceso
                        <methodname>setAllowEmpty()</methodname> y
                        <methodname>getAllowEmpty()</methodname> . Esta bandera
                    es <constant>TRUE</constant> por defecto. </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>autoInsertNotEmptyValidator</emphasis> : bandera
                    indicando insertar o no un validador 'NotEmpty' cuando un
                    elemento es requerido. Por defecto, esta bandera es
                        <constant>TRUE</constant> . Establezca la bandera con
                        <methodname>setAutoInsertNotEmptyValidator($flag)</methodname>
                    y determine el valor con
                        <methodname>autoInsertNotEmptyValidator()</methodname> .
                </para>
            </listitem>
        </itemizedlist>

        <para> Los elementos del formulario pueden requerir metainformación
            adicional. Para elementos <acronym>XHTML</acronym> del formuladio,
            por ejemplo, puede querer especificar atributos como el class o id.
            Para facilitar esto hay un conjunto de métodos de acceso: </para>

        <itemizedlist>
            <listitem>
                <para>
                    <emphasis>setAttrib($name, $value)</emphasis> : añade un
                    atributo </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>setAttribs(array $attribs)</emphasis> : como
                    addAttribs(), pero sobreescribiendo </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>getAttrib($name)</emphasis> : recupera el valor de
                    solo un atributo </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>getAttribs()</emphasis> : recupera todos los
                    atributos como pares clave/valor </para>
            </listitem>
        </itemizedlist>

        <para> La mayoría de las veces, como sea, puede simplemente acceder a
            ellos como propiedades de objeto, ya que
                <classname>Zend_Form_Element</classname> utiliza la sobrecarga
            para facilitar el acceso a ellos: </para>

        <programlisting language="php"><![CDATA[
// Equivalente a $element->setAttrib('class', 'text'):
$element->class = 'text;
]]></programlisting>

        <para>Por defecto, todos los atributos son pasados al auxiliar vista
            usado por el elemento durante la generación, y generados como
            atributos de la etiqueta del elemento.</para>
    </sect2>

    <sect2 id="zend.form.elements.standard">
        <title>Elementos Estándar</title>

        <para>
            <classname>Zend_Form</classname> contiene un buen número de
            elementos estándar; por favor lea el capítulo <link
                linkend="zend.form.standardElements">Elementos Estándar</link>
            para todos los detalles. </para>
    </sect2>

    <sect2 id="zend.form.elements.methods">
        <title>Métodos de Zend_Form_Element</title>

        <para>
            <classname>Zend_Form_Element</classname> tiene muchos, muchos
            métodos. Lo que sigue es un sumario de sus funciones, 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>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>

            <listitem>
                <para>Propiedades:</para>
                <itemizedlist>
                    <listitem>
                        <para>
                            <methodname>setName($name)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>getName()</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>setValue($value)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>getValue()</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>getUnfilteredValue()</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>setLabel($label)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>getLabel()</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>setDescription($description)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>getDescription()</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>setOrder($order)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>getOrder()</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>setRequired($flag)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>getRequired()</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>setAllowEmpty($flag)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>getAllowEmpty()</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>setAutoInsertNotEmptyValidator($flag)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>autoInsertNotEmptyValidator()</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>setIgnore($flag)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>getIgnore()</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>getType()</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>setAttrib($name, $value)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>setAttribs(array $attribs)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>getAttrib($name)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>getAttribs()</methodname>
                        </para>
                    </listitem>
                </itemizedlist>
            </listitem>

            <listitem>
                <para>Cargadores y rutas de plugin:</para>
                <itemizedlist>
                    <listitem>
                        <para>
                            <methodname>setPluginLoader(Zend_Loader_PluginLoader_Interface
                                $loader, $type)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>getPluginLoader($type)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>addPrefixPath($prefix, $path, $type =
                                null)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>addPrefixPaths(array $spec)</methodname>
                        </para>
                    </listitem>
                </itemizedlist>
            </listitem>

            <listitem>
                <para>Validación:</para>
                <itemizedlist>
                    <listitem>
                        <para>
                            <methodname>addValidator($validator,
                                $breakChainOnFailure = false, $options =
                                array())</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>addValidators(array
                                $validators)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>setValidators(array
                                $validators)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>getValidator($name)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>getValidators()</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>removeValidator($name)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>clearValidators()</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>isValid($value, $context =
                                null)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>getErrors()</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>getMessages()</methodname>
                        </para>
                    </listitem>
                </itemizedlist>
            </listitem>

            <listitem>
                <para>Filtros:</para>
                <itemizedlist>
                    <listitem>
                        <para>
                            <methodname>addFilter($filter, $options =
                                array())</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>addFilters(array $filters)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>setFilters(array $filters)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>getFilter($name)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>getFilters()</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>removeFilter($name)</methodname>
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <methodname>clearFilters()</methodname>
                        </para>
                    </listitem>
                </itemizedlist>
            </listitem>

            <listitem>
                <para>Generación:</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>
        </itemizedlist>
    </sect2>

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

        <para> El constructor de <classname>Zend_Form_Element</classname> acepta
            tanto una matriz de opciones como un objeto
                <classname>Zend_Config</classname> conteniendo opciones, y esto
            puede configurarse usando <methodname>setOptions()</methodname> o
                <methodname>setConfig()</methodname> . Hablando de manera
            general, las claves son nombradas de la siguiente manera: </para>

        <itemizedlist>
            <listitem>
                <para> Si 'set' + clave se refiere a un método de
                        <classname>Zend_Form_Element</classname> , entonces el
                    valor provisto será pasado a el método. </para>
            </listitem>

            <listitem>
                <para>De otra manera, el valor será usado para establecer un
                    atributo.</para>
            </listitem>
        </itemizedlist>

        <para>Excepciones a la regla incluyen las siguientes:</para>

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

            <listitem>
                <para>Los siguientes setters no pueden establecerse de esta
                    manera:</para>

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

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

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

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

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

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

        <para>Como ejemplo, aquí esta un archivo de configuración pasado para
            cada tipo de dato configurable:</para>

        <programlisting language="ini"><![CDATA[
[element]
name = "foo"
value = "foobar"
label = "Foo:"
order = 10
required = true
allowEmpty = false
autoInsertNotEmptyValidator = true
description = "Foo elements are for examples"
ignore = false
attribs.id = "foo"
attribs.class = "element"
; sets 'onclick' attribute
onclick = "autoComplete(this, '/form/autocomplete/element')"
prefixPaths.decorator.prefix = "My_Decorator"
prefixPaths.decorator.path = "My/Decorator/"
disableTranslator = 0
validators.required.validator = "NotEmpty"
validators.required.breakChainOnFailure = true
validators.alpha.validator = "alpha"
validators.regex.validator = "regex"
validators.regex.options.pattern = "/^[A-F].*/$"
filters.ucase.filter = "StringToUpper"
decorators.element.decorator = "ViewHelper"
decorators.element.options.helper = "FormText"
decorators.label.decorator = "Label"
]]></programlisting>
    </sect2>

    <sect2 id="zend.form.elements.custom">
        <title>Elementos personalizados</title>

        <para> Usted puede crear sus propios elementos personalizados
            simplemente extendiendo la clase
                <classname>Zend_Form_Element</classname> . Las razones comunes
            para hacer esto incluyen: </para>

        <itemizedlist>
            <listitem>
                <para>Elementos que comparten validadores y/o filtros comunes
                </para>
            </listitem>

            <listitem>
                <para>Elementos que tienen decoradores con funcionalidad
                    personalizada</para>
            </listitem>
        </itemizedlist>

        <para> Hay dos métodos típicamente usados para extender un elemento:
                <methodname>init()</methodname> , el cual puede usarse para
            añadir una lógica de inicialización personalizada a su elemento, y
                <methodname>loadDefaultDecorators()</methodname> , el cual puede
            usarse para establecer una lista de decoradores usados por su
            elemento de manera predeterminada. </para>

        <para> Como un ejemplo, digamos que todos los elementos de tipo texto en
            un formulario que está creando, necesitan ser filtrados con
                <methodname>StringTrim</methodname> , validados con una
            expresión regular, y que quiere usar un decorador personalizado que
            ha creado para mostrarlos, 'My_Decorator_TextItem'; adicionalmente,
            tiene un número de atributos estándars, incluyendo 'size',
            'maxLength', y 'class' que quisiera especificar. Puede definir un
            elemento tal como sigue: </para>

        <programlisting language="php"><![CDATA[
class My_Element_Text extends Zend_Form_Element
{
    public function init()
    {
        $this->addPrefixPath('My_Decorator', 'My/Decorator/', 'decorator')
             ->addFilters('StringTrim')
             ->addValidator('Regex', false, array('/^[a-z0-9]{6,}$/i'))
             ->addDecorator('TextItem')
             ->setAttrib('size', 30)
             ->setAttrib('maxLength', 45)
             ->setAttrib('class', 'text');
    }
}
]]></programlisting>

        <para>Entonces puede informar a su objeto formulario acerca del prefijo
            de ruta para elementos de ese tipo, y comenzar creando
            elementos:</para>

        <programlisting language="php"><![CDATA[
$form->addPrefixPath('My_Element', 'My/Element/', 'element')
     ->addElement('foo', 'text');
]]></programlisting>

        <para> El elemento 'foo' será ahora del tipo
                <methodname>My_Element_Text</methodname> , y mostrará el
            comportamiento que ha especificado. </para>

        <para> Otro método que puede querer sobreescribir cuando extienda
                <classname>Zend_Form_Element</classname> es el método
                <methodname>loadDefaultDecorators()</methodname> . Este método
            carga condicionalmente un grupo de decoradores predefinidos para su
            elemento; puede querer sustituir su propio decorador en su clase
            extendida: </para>

        <programlisting language="php"><![CDATA[
class My_Element_Text extends Zend_Form_Element
{
    public function loadDefaultDecorators()
    {
        $this->addDecorator('ViewHelper')
             ->addDecorator('DisplayError')
             ->addDecorator('Label')
             ->addDecorator('HtmlTag',
                            array('tag' => 'div', 'class' => 'element'));
    }
}
]]></programlisting>

        <para> Hay muchas maneras de personalizar elementos; asegúrese de leer
            la documentación de la <acronym>API</acronym> de
                <classname>Zend_Form_Element</classname> para conocer todos los
            métodos disponibles. </para>
    </sect2>
</sect1>
