zend-framework zend-form zend-form-sub-form

zend framework - Uso del decorador ViewScript en subformularios anidados(formulario Zend)



zend-framework zend-form (4)

¿Estás tratando de enviar tu formulario usando <?php echo $this->form; ?> <?php echo $this->form; ?> desde su script de vista?

Eso funciona bien para formularios simples, pero para mis formas más complejas tiendo a renderizar cada elemento individualmente, pero no es necesario usar el decorador de ViewScript en cada elemento individual para hacer esto. Intente algo como esto desde su script de vista:

<div class="form"> <fieldset> <legend>Some Form Name</legend> <form action="<?php echo $this->escape($this->form->getAction()) ?>" method="<?php echo $this->escape($this->form->getMethod()) ?>" enctype="multipart/form-data"> <?php echo $this->form->id; // render the id element here ?> <div class="half"> <?php echo $this->form->name; // render the user name field here ?> </div> <div class="half"> <?php echo $this->form->description; // render the description element here ?> </div> <div class="clear"></div> <div class="half"> <?php echo $this->form->address1; // render the address ?> </div> <div class="half"> <?php echo $this->form->address2; // render address2 ?> </div> <div class="clear"></div> <div class="third"> <?php echo $this->form->zip; // render zip code ?> </div> <div class="third"> <?php echo $this->form->city; // render city ?> </div> <div class="third"> <?php echo $this->form->state; // render state ?> </div> <div class="clear"></div> <div class="half"> <?php echo $this->form->country; // render country ?> </div> <div class="clear"></div> <?php echo $this->form->submit; ?> </form> </fieldset> </div>

Así es como hago la mayoría de mis formularios porque quiero que algunos elementos ocupen la mitad del ancho y otros que todo el ancho.

Sorprendentemente, la guía de referencia no te dice que puedes hacer esto. Me parece recordar una página sobre esto en el pasado pero no puedo encontrarlo ahora. Cuando comencé con Zend Framework, pensé que la única forma en que podía hacer que mi formulario saliera exactamente como yo quería era crear decoradores complejos, pero ese no es el caso.

Matthew Weier O''Phinney tiene una gran publicación en el blog sobre la representación de decoradores Zend_Form individualmente, lo que explica lo que hice arriba. Espero que agreguen esto a la primera página de Zend Form porque eso fue desalentador para mí al principio. El hecho es que el 90% de mis formularios rinden elementos de forma individual en lugar de solo hacer eco de la forma en sí.

Nota: Para evitar que ZF adjunte mis elementos de formulario en las etiquetas dt y dd, aplico este decorador a todos mis elementos de formulario estándar. Tengo una clase de formulario base de la cual extiendo todos mis formularios, así no tengo que repetir esto en todas partes. Este es el decorador del elemento, así que puedo usar etiquetas para encerrar mis elementos.

public $elementDecorators = array( ''ViewHelper'', ''Errors'', array(''Description'', array(''tag'' => ''p'', ''class'' => ''description'')), array(''HtmlTag'', array(''tag'' => ''div'', ''class'' => ''form-div'')), array(''Label'', array(''class'' => ''form-label'', ''requiredSuffix'' => ''*'')) );

Para mis botones de envío que uso

public $buttonDecorators = array( ''ViewHelper'', array(''HtmlTag'', array(''tag'' => ''div'', ''class'' => ''form-button'')) );

Quiero usar un script de vista para representar mi formulario Zend, ya que parece ser la mejor forma de controlar el diseño / diseño del formulario mientras sigo usando las clases Zend_Elements.

Desde el script de vista, represento el elemento con $this->element->getElement(''elementName'') .

Tengo problemas con los nombres de los elementos. Esto es en realidad una subforma dentro de una subforma dentro de una forma.

Cuando utilicé los decoradores de FormElements, el nombre completamente calificado de los elementos era form [subForm] [subForm] [element], que era bueno. Wehn I se trasladó a los decoradores viewScript, cambió a subformulario [subFormulario] [elemento].

Entendí que necesito usar el decorador PrepareElements para solucionar esto, pero esto causó que el nombre cambiara de [subForm] [form] [subForm] [subForm] [elements] (duplicó los primeros dos nombres al comienzo).

¿Alguna idea de cómo debo manejar esto?

Gracias.

ACTUALIZACIÓN: Intenté depurar PrepareElements y realmente no entiendo qué está haciendo. Parece que funciona bien en la primera iteración, pero luego vuelve a agregar el prefijo form [subform] cuando se ejecuta en uno de los subformularios intermedios.

Cuando no estoy usando el decorador PrepareElements, me falta el prefijo "formulario" en los nombres (es decir, en lugar de la forma [subFormulario] [elemento], obtengo solo subformulario [elemento]).

Puede ser que puedo arreglar esto de alguna manera?

Traté de cambiar el belongsTo pero eso solo reemplazó el prefijo "subForm".

En realidad, parece que lo que falta es un método belongsTo en el subformulario.

De nuevo, todo esto se debe al decorador de ViewScript. Funciona bien con los decoradores de FormElements.

ACTUALIZACIÓN 2: Solo para aclarar, no me importaría que este nombre cambie, pero hace que mis campos no se llenen cuando llamo a form-> populate.

Editar: creo que reduje el problema a esto: cuando recupero mis valores en setDefaults, se ordenan así:

array( /"formElements1-name/" => value1... /"subFormName/" => array( /"parentFormName/" => array( /"subFormName/" => subForm-values-array ) )

... El principal problema aquí es el "parentFormName" => "subFormNAme".. ¿qué se repite? Ya estoy en la forma principal. Supongo que esto se debe a que he establecido setElementsBelongTo(formName[subFormName]) , pero si no lo hiciera, obtendría mis valores de subformulario completamente separados del formulario.

es decir, los valores array = array (/ "formName /" => array (formValues), / "subFormNAme /" => array (subFormValues)

, mientras que lo exijo para ser

array( formName => array( subFormNAme => values-array ) )...

¿Es posible hacer que esto funcione?


La solución actual es usar el decorador PrepareElements en los subformularios con un cambio: elimine la llamada recursiva en el código PrepareElements. Además, no se requiere "setElementsBelongTo".

Esto parece generar los nombres e ids correctos.


La solución sería usar la propiedad de elemento de formulario belongsTo() .
Ejemplo:

new Zend_Form_Element_Text(''<elementName>'', array(''belongsTo'' => ''<subformName>''))

De esta forma, el método render () usará un nombre de elemento de formulario como

name="<subformName>[<elementName>]"


Tuve el mismo problema y lo resolví con un decorador

1: crear un subformulario genérico con elementos

2: usar un decorador específico con PrepareElements

3: Cambiar el formulario a una matriz con setIsArray (verdadero)

Ejemplo:

Formar

$i = 4; for($i = 0; $i < $nbReclam ; $i++) { $rowForm = new Zend_Form_SubForm($i); $name= new Zend_Form_Element_Textarea(''name''); $rowForm->addElement($name); $this->addSubForm($rowForm, $i); } $this->setDecorators(array( ''PrepareElements'', array(''ViewScript'', array(''viewScript'' => ''myDecorator.phtml'')), )); $this->setIsArray(true);

Decorador

<table> <thead> <tr> <th>N°</th> <th>Name</th> </tr> </thead> <tbody> <?php foreach ($this->element->getSubForms() as $subForm) : ?> <tr> <td> <?php echo $i++?> </td> <?php foreach ($subForm->getElements() as $row) : ?> <td><?php echo $row ?></td> <?php endforeach ?> </tr> <?php endforeach ?> </tbody> </table>

Disfrutar

Lo siento por mi inglés, soy francés