php - Zend Form: ¿Cómo hago que se doble a mi voluntad?
zend-framework zend-form (14)
He leído el manual muchas veces, he recorrido las publicaciones que ofrece Google sobre el tema, incluso he comprado un par de libros que tratan sobre ZF. Ahora, ¿por qué estoy todavía confundido?
Puedo, usando Zend_Form, hacer una forma que valide y funcione bien. Lo que no puedo hacer es crear un formulario que se vea exactamente como quiero que se vea con los mensajes de error que quiero que tenga. Quiero botones personalizados, quiero diseños originales, quiero insertar texto en el medio del formulario, etc.
¿Alguien tiene una manera simple de lograr este tipo de cosas? ¿Algo que me hace sentir como el marco de trabajo me está ahorrando tiempo en lugar de costarte? Podría renunciar a Zend Form ... hacer mi propia forma, hacer que su acción llegue a una página para validar y procesar los datos publicados, y podría hacerlo lo más rápido que pueda escribir, pero realmente quiero "obtener" esto y poder para usarlo como aparentemente se pretendía.
¿Algún consejo? Cualquier "cómo hacerlo" simple para botones personalizados, diseños originales y básicos (o más avanzados, ya que hay un montón de tutoriales básicos que omiten los problemas más difíciles) "hacer las cosas" con la forma de Zend.
Actualmente tenemos el nuevo y brillante Zend/Form
que es incluso más complejo que el antiguo pero también mucho más controlable, encapsulado y potente. Entonces, lo que dije a continuación no se aplica. El nuevo componente es en mi humilde opinión una gran mejora porque ...
- ... te da un control total sobre cómo quieres renderizar tu formulario, necesitas escribir un poco más de código de vista, pero vale la pena
- ... separa datos, lógicas y vistas en la medida de lo posible
- ... hace uso de los elementos de formulario HTML5
- ... le da muchas opciones sobre cómo quiere juntar sus formularios, por ejemplo, hidratación, anotaciones, etc.
Respuesta anterior con respecto a Zend_Form
Realmente no puedo ayudar probablemente porque tengo exactamente el mismo problema. Creo que los decoradores de Zend_Form son poderosos, pero con mucho, los menos amigables con los programadores y la pieza no intuitiva de ZF que he visto hasta ahora, y he usado una parte importante de ZF en varios proyectos.
Dicho esto, solo puedo dar algunas pistas de mi experiencia:
- los filtros son fáciles de usar sin usar la forma
- la mayoría, si no todas, las cosas que quieres lograr se hacen con la ayuda de decoradores
- Comencé con formas pequeñas y agregué cosas por pieza, pero no obtengo algunas de las cosas que estoy haciendo en algunos de mis formularios porque el resultado se basa en prueba y error (principalmente con los decoradores)
- Tengo información de la lista de correo de zend que no pude encontrar en ninguna parte de la web
De las preguntas relacionadas a esto en el lado derecho es obvio que hay una falta de documentación exhaustiva para Zend_Form, especialmente dado que es de naturaleza no intuitiva. Realmente me gustaría ver a los chicos de ZF hacer algo al respecto tanto como me gusta Zend Framework.
Entonces, esta respuesta probablemente sea solo para hacerle saber que usted no es el único que tiene este problema.
¡o alternativamente podrías usar trucos de mente Jedi por supuesto!
El consejo de Barrett Conrad es lo que hubiera sugerido. Además, tenga en cuenta que no necesita usar un objeto de formulario para representar su formulario.
Una cosa que podría hacer es crear un formulario en su script de vista que tenga elementos con el mismo nombre que una clase de formulario.
Su formulario HTML:
<form action="/login/" method="post">
<fieldset>
<label for="username">Username:</label>
<input type="text" size="10" name="username" />
<label for="password">Password:</label>
<input type="password" size="10" name="password" />
<input type="submit" />
</fieldset>
</form>
Tu clase:
class LoginForm extends Zend_Form
{
public function init()
{
$username = $this->createElement(''text'',''username'');
$username->setRequired(true);
$this->addElement($username);
$password = $this->createElement(''password'',''password'');
$password->setRequired(true);
$this->addElement($password);
}
}
Su clase de formulario refleja su formulario HTML, cada elemento de su clase tiene sus propios validadores y requisitos. De vuelta en su acción, puede crear una instancia de su clase de formulario y validar sus vars de publicación / obtención contra esa forma:
$form = new LoginForm();
if ($this->_request->isPost()) {
if ($form->isValid($this->_request->getParams())) {
// do whatever you need to do
} else {
$this->view->errors = $form->getMessages();
}
}
Puede mostrar los mensajes de error en la parte superior de su formulario en un grupo, utilizando este método.
Este es un ejemplo básico, pero le permite tener un control total sobre la presentación de su formulario sin perder el tiempo para aprender a usar decoradores. Gran parte de la fortaleza de Zend_Form reside en sus propiedades de validación y filtrado, en mi opinión. Esto te da esa fuerza. El principal inconveniente de una solución como esta es que su formulario HTML de script de vista puede quedar fuera de sincronización con su clase de formulario.
El primer consejo de Sean McSomething es el camino a seguir para mí. Siempre he pensado que hacer <?php echo $this->form ?>
Para renderizar un formulario es demasiado mágico. Sin embargo, daré un paso más y renderizaré decoradores individuales en lugar de elementos individuales a través de los métodos mágicos $element->renderDecorator()
. De esta forma, no tendrá que preocuparse por el orden en que definió sus decoradores. Solo necesita que estén allí, y no tendrá que agregar esos molestos y poco intuitivos decoradores HtmlTag
. Hice una publicación de blog sobre esto .
Escribí algunas subclases a Zend_Form y a los decoradores para que diseñaran el formulario en una <table>. Incluso tenía algunos trucos especiales para hacer cosas como mostrar múltiples botones de presentación en la misma fila.
Tomó un día completo de pirateo para que funcione. Fue escrito contra Zend 1.5.1 por lo que no sé si funcionará con la versión actual, pero si está interesado probablemente podría cargar la fuente en alguna parte.
Esta parece ser una queja muy común con Zend Forms.
(Sé que los puristas de CSS me despojarán de usar tablas para diseñar formularios, y aunque estoy de acuerdo en que CSS es mejor para la mayoría de las cosas, aún no he visto un buen diseño de formulario con CSS que no se vea Como con las tablas, las formas "funcionan" prácticamente en todos los navegadores que necesito.
EDITAR: Bien, hablando de kludges feos, he puesto mi código para producir formas tabulares zend en github. Ve here para verlo. (Porque lo pidió gaoshan88).
Lamentablemente, se omiten los problemas más complejos porque, sin un objetivo o propósito específico real en mente, es realmente difícil escribir un ejemplo o cómo hacerlo. Pasé un tiempo ayudando a otro desarrollador aquí en SO que quería modificar la forma en que se muestran los elementos ocultos , pero su caso era muy específico, por lo que era más fácil profundizar en detalles.
La mayoría de las tareas más complejas se reducen a la extensión del ayudante predeterminado para un tipo de campo específico. Por ejemplo, tuve un proyecto en el que quería aplicar el "error" de clase a todos los campos que no pasaron la validación después de que se había enviado un formulario en lugar de escribir el texto de error de validación:
<label for="field">Label:</label>
<input type="text" name="field" id="field" class="error">
Fue un proceso bastante complejo porque el elemento de formulario real no está disponible para el asistente de vista de forma predeterminada, por lo que el asistente no puede verificar si el elemento tiene un error de validación. Entonces realicé el siguiente proceso:
- Tuve que crear un asistente de vista de cliente para cada tipo de campo al que quería aplicar la clase de "error". En él,
formXXX()
métodoformXXX()
yformXXX()
una verificación para ver si el elemento tenía un error. Además, agregué un métodosetElement()
que el decorador podría llamar para establecer una instancia del elemento para que mi ayudante pudiera verificar si había errores. - Luego tuve que anular el
Zend_Form_Decorator_ViewHelper
predeterminado. En él, accedí a la vista e instalé el helper para el tipo de elemento de formulario y verifiqué la existencia del métodosetElement()
que creé en mi asistente de visualización, configurándolo si existía. Al hacer esto, podría extender algunos tipos de elementos de formulario y no otros sin destruir todo el script. - En mi función init () para cada formulario, tuve que agregar una nueva ruta de prefijo de elemento (
addElementPrefixPath(''My_Form_Decorator''), ''path/to/decorator'')
) que apuntaba a mi nuevo decorador de formularios. - Finalmente, tuve que agregar la ruta de ayuda a mi aplicación para que Zend Framework pudiera encontrar los ayudantes que había creado en el primer punto:
addHelperPath(''/path/to/helpers'', ''My_View_Helper'');
Puedes ver por qué escribir tutoriales complejos realmente requiere problemas del mundo real. La gran parte de la configuración de este tipo de ayudantes, o esquemas decorativos complejos es que, todo sea molesto desde el principio, le permite crear fácilmente muchas formas que se adhieren al mismo esquema de diseño y modificar su producción de manera uniforme muy rápidamente si los cambios necesita ser hecho. Pero si, por otro lado, sientes que pasas una gran cantidad de tiempo pensando en cómo hacer lo que debería ser una tarea simple para el beneficio de una forma, ¡te lo saltearía!
Si desea ayuda para algo más específico, sin embargo, estaría más que feliz de ayudar. Haga otra pregunta (o actualice esta) y haré todo lo posible para ayudar.
Matthew Weier O''Phinney ha comenzado una serie de publicaciones en blogs sobre los decoradores de Zend_Form:
No estoy seguro si Zend ya tiene esa característica, pero una solución rápida sería extender la clase, hacer que acepte una plantilla html.
Por ejemplo:
<?php
$form = new zend_form_whatever($field_list + $validators + $template);
echo $form;
?>
modelo:
<form id="my_custom_form">
<label>{label.email}</label>
{input.email}
<span class="red">{error.email}</span>
<div>
{label.password}
{error.password}
{input.password}
</div>
<div class="purple">{input.submit}<div>
</form>
Para agregar a lo que se dijo:
No temas a los decoradores, los usarás mucho si decides quedarte con Zend_Form. Es bastante sencillo una vez que lo ''obtienes'', desafortunadamente los documentos son débiles y jugar con él es casi la única forma de llegar allí.
Los decoradores ViewScript y ViewHelper le brindan mucha potencia.
No temas buscar en la fuente los diferentes decoradores que existen y ver cómo están haciendo las cosas (obtuve una buena cantidad de información comparando los decoradores originales con los dojo).
Creo que lo que Sean sugirió es que no necesitas llamar a form-> render, puedes usar algo como esto en tu viewcript.
<someHtmlThingy name="blah" value="<?php echo $this->formInstance->getElement(''whatever'')->getValue(); ?>" />
Trabajé en un proyecto (antes de Zend_Form) donde construimos conjuntos de validadores y utilizamos guiones de vista estándar hasta el final. Fue un poco más de trabajo (fontanería para los mensajes de error y similares), pero no excesivo en comparación con la creación de elementos con Zend_Form.
Probablemente ya hayas resuelto esto, pero he estado trabajando y necesitaba una solución similar.
form->getSubform(''subform''); foreach ($subform as $key => $value) { //some markup and custom code here print $value; //some markup and custom code here } ?>
dentro del ciclo foreach, puede agregar marcas de tabla. Si ha nombrado las claves para las filas de la tabla de forma adecuada, deben coincidir con las claves de formulario. Incluso podría usar un bucle que tome el subformulario apropiado por clave, o incluso un elemento por una clave. puede omitir el bucle foreach si conoce las claves, y simplemente diga print $ subform [''somekey'']; suponiendo que establezca el formulario principal diciendo $ form-> setIsArray (true); (No estoy seguro si esa última parte es estrictamente necesaria, pero para formas complicadas, debe establecerse así de todos modos.
Eliminé los decoradores predeterminados para poder tener un control completo de la impresión dentro de cada elemento. Zend_Form debe tener un método incorporado para agarrar elementos individuales con más facilidad ... pero creo que funciona bastante bien.
Espero que sea útil para alguien!
RESPUESTA AQUÍ. Espero que te ayude. Revisé la enorme cantidad de información hasta que la encontré.
<table>
<tr>
<td>Page name: *</td>
<td><?php echo $this->pageForm->header_title;?></td>
</tr>
<tr>
<td>H1 tag: *</td>
<td><?php echo $this->pageForm->h1_tag;?></td>
</tr>
<tr>
<td>Page URL: *</td>
<td><?php echo $this->pageForm->url;?></td>
</tr>
<tr>
<td>Meta Description: </td>
<td><?php echo $this->pageForm->meta_description;?></td>
</tr>
<tr>
<td>Meta Keywords: </td>
<td><?php echo $this->pageForm->meta_keywords;?></td>
</tr>
<tr>
<td>Short Description: *</td>
<td><?php echo $this->pageForm->short_description;?></td>
</tr>
<tr>
<td colspan="2"><a href="<?php echo $this->websiteUrl;?>backend_template/list?placeValuesBeforeTB_=savedValues&TB_iframe=true&height=200&width=300&modal=true"
title="add a caption to title attribute / or leave blank" class="thickbox">Open iFrame Modal</a></td>
<td>
<a href="<?php echo $this->websiteUrl;?>backend_template/list?placeValuesBeforeTB_=savedValues&TB_iframe=true&height=200&width=300&modal=true" onclick="javascript:getDataFromAddPage()" title="Select Template For Page" class="thickbox" > TEST FORM </a>
</td>
</tr>
<tr>
<td>Featured: </td>
<td><?php echo $this->pageForm->featured;?></td>
</tr>
<tr>
<td>Mark as 404: </td>
<td><?php echo $this->pageForm->is_404page;?></td>
</tr>
<tr>
<td>Show in Navigation Menu: </td>
<td><?php echo $this->pageForm->in_navmain;?></td>
</tr>
<tr>
<td>Show in Static Menu:</td>
<td><?php echo $this->pageForm->in_navstatic;?></td>
</tr>
<tr>
<td><?php echo $this->pageForm->submit;?></td>
<td><?php echo $this->pageForm->button_close;?></td>
</tr>
</table>
Renderice cada elemento individualmente en su vista, por ejemplo
<!-- view script here -->
<form method="POST">
Name: <?php echo $this->myForm->getElement(''name'')->render(); ?>
some other text between the fields
Birthdate: <?php echo $this->myForm->getElement(''birthdate'')->render(); ?>
<input type="submit" />
</form>
Esto mantiene la capacidad de utilizar los ayudantes de visualización Zend_Form (es decir, para mostrar mensajes de error y mantener los valores de los campos del formulario cuando falla la validación), pero le ofrece una capacidad de personalización completa.
Si desea ir más allá, apague los decoradores predeterminados de los elementos de formulario individuales y luego adjunte los suyos propios para personalizar aún más exactamente qué etiquetas se utilizan (es decir, para mensajes de error y etiquetas) o no use decoradores (otros que renderizar el elemento de formulario en sí) y luego escribir todo el HTML circundante manualmente. Completa la capacidad de personalización sin perder los beneficios de Zend_Form, tanto a nivel de formulario como a nivel de vista.
Saltarse los decoradores de todo el formulario (por ejemplo, imprimir elementos individuales del formulario en lugar de basarse en el asistente de visualización estándar del formulario para manejar todo) es una forma de recuperar un montón de control.
Otra opción es simplemente codificar manualmente su formulario y solo usar ZF para manejar la validación y el filtrado.
Si solo desea agregar marcas arbitrarias antes o después de los elementos de su formulario sin utilizar el decorador de ViewScript, puede usar mi decorador de AnyMarkup:
Por ejemplo, aquí está cómo anteponer un campo de entrada con una imagen dentro de una etiqueta contenedora (las necesidades incluyen rutas para que la carga automática esté configurada correctamente):
$form->addElement(''text'', ''my_field'', array( ''label'' => ''Enter Info:'', ''decorators'' => array( ''ViewHelper'', array(''AnyMarkup'', array( ''markup'' => ''<span class="imgwrapper">''. ''<img src="info.png" alt="info icon"/></span>''), ''placement'' => ''prepend'' ), ''HtmlTag'', ''Label'' ) );
whycantitbemorethan25c los mencionó anteriormente, pero ViewScripts proporciona un control extremadamente detallado para los formularios de representación. Zend_Form debe ser rápido, por lo que asume muchos valores predeterminados, como decoradores estándar, y ordena el elemento de la misma forma en que se agregaron al objeto de formulario. Con ViewScript puede omitir gran parte de eso y colocar todos sus elementos como desee dentro de HTML normal.
Sin embargo, no se salte el concepto de Decoradores. Diseñan los elementos individuales incluso si se usan en un ViewScript más adelante. Por ejemplo, puede usarlos para mensajes de error como otros han sugerido.
Si tiene una forma muy complicada que tiene múltiples puntos de datos con acciones similares (piense en una lista de usuarios con botones activos / inactivos y un botón de eliminar para cada uno), debería considerar Zend_Form_SubForm . Los subformularios pueden utilizar los ViewScripts al igual que los formularios normales, y si coloca en cascada un formulario con un ViewScript con subformularios con sus propios ViewScripts, terminará con una lógica y presentación muy bien definida que es mucho más poderosa que simplemente una forma directa.