php - documentacion - zend framework 3 tutorial
Cómo quitar todos los DtDdWrappers y etiquetas en Zend Form Elements (7)
Sé que puedo eliminar las cosas extra de cada elemento individualmente, como
$button ->removeDecorator(''DtDdWrapper'')
->removeDecorator(''HtmlTag'')
->removeDecorator(''Label'');
Me preguntaba si puedo lograr lo mismo para todos mis elementos en una forma zend?
¿Y cómo se elimina el dl envolviendo el formulario?
Creo que la única forma de hacerlo es extender Zend_Form y luego reemplazar las funciones loadDefaultDecorators () y render () de la siguiente manera. Vea si esto funciona para usted.
class App_Form extends Zend_Form
{
public function loadDefaultDecorators()
{
if ($this->loadDefaultDecoratorsIsDisabled()) {
return $this;
}
$decorators = $this->getDecorators();
if (empty($decorators)) {
$this->addDecorator(''FormElements'')
->addDecorator(''Form'');
}
return $this;
}
public function render(Zend_View_Interface $view = null)
{
$elements = $this->getElements();
foreach($elements as $element){
$element->setDecorators(array(
''ViewHelper'',
''Errors'',
array(''Description'', array(''tag'' => ''p'', ''class'' => ''description'')),
''Label'',
));
}
$content = parent::render($view);
return $content;
}
}
Editar:
Creo que este método seguirá siendo un inconveniente, ya que la nueva función render () borrará todas las etiquetas que hayas agregado a tus elementos. Para evitar esto, necesitaría extender Zend_Form_Element y reemplazar su método loadDefaultDecorators () de la misma manera que lo he hecho aquí para el formulario.
En mi opinión, y probablemente el de muchos otros desarrolladores que usan Zend_Form, no debería haber etiquetas en el formato de marcado por defecto que no sean las etiquetas <form>
, <input>
y <label>
. El desarrollador puede agregar cualquier otra cosa con los métodos existentes.
Las siguientes 4 líneas de código funcionan para mí
$elements = $this->getElements();
foreach($elements as $element) {
$element->removeDecorator(''DtDdWrapper'')
->removeDecorator(''HtmlTag'')
->removeDecorator(''Label'');
}
Encantador
Llegar un poco tarde al hilo, pero funcionó para mí
foreach( $this->getElements() as $el )
{
foreach( $el->getDecorators() as $dec )
{
if( $dec instanceof Zend_Form_Decorator_HtmlTag ||
$dec instanceof Zend_Form_Decorator_Label )
{
$dec->setOption( ''tag'', ''li'' );
};
};
};
Markus, aquí hay una solución que uso que parece funcionar bien, espero que sea adecuada para ti.
Primero, para renderizar el formulario sin etiqueta <dl>
, necesitamos configurar los decoradores en el objeto de formulario. Desde dentro de una clase que extiende Zend_Form, deberías llamar a Zend_Form->setDecorators()
pasando una matriz de decoradores de formularios.
De la guía de referencia:
The default decorators for Zend_Form are FormElements, HtmlTag (wraps in a definition list), and Form; the equivalent code for creating them is as follows:
$form->setDecorators(array(
''FormElements'',
array(''HtmlTag'', array(''tag'' => ''dl'')),
''Form''
));
Para envolver el formulario en algo que no sea un dl, usamos los decoradores anteriores pero cambiamos el dl a cualquier etiqueta que usemos, normalmente uso un div
de clase que veremos más adelante.
A continuación, los elementos deben ser tratados. Los elementos Zend_Form tienen diferentes decoradores para diferentes tipos de elementos. Los siguientes grupos de tipos de elementos tienen cada uno un conjunto distinto de decoradores: [Enviar y botón], [Captcha], [Archivo], [Imagen] y [Radio *]. El decorador de radio es muy similar a los elementos estándar, excepto que no especifica el atributo for
dentro de la etiqueta.
Todos los demás elementos de formulario, texto, contraseña, seleccionar, casilla de verificación, etc. usan el mismo conjunto de decoradores predeterminados.
Para eliminar las etiquetas dd / dt de un elemento de formulario individual, deberíamos aplicarle nuestro propio conjunto de decoradores. Aquí hay un ejemplo que no usa etiquetas dd / dt:
array(
''ViewHelper'',
''Errors'',
array(''Description'', array(''tag'' => ''p'', ''class'' => ''description'')),
array(''HtmlTag'', array(''class'' => ''form-div'')),
array(''Label'', array(''class'' => ''form-label''))
);
Esto ajustará cada elemento del formulario en una etiqueta div con la clase form-div
. El problema es que tienes que aplicar este conjunto de decoradores a TODOS los elementos que no quieras envolver en las etiquetas dd / dt, lo que puede ser un poco problemático.
Para resolver este problema, creo una clase que se extiende desde Zend_Form y le doy un comportamiento predeterminado y decoradores que son diferentes de los decoradores predeterminados para Zend_Form.
Aunque no podemos dejar que Zend_Form asigne automáticamente los decoradores correctos a tipos de elementos específicos (puede asignarlos a nombres de elementos específicos), podemos establecer un valor predeterminado y darnos un acceso fácil a los decoradores desde un solo lugar, por lo que si necesitan para cambiar, se pueden cambiar fácilmente para todas las formas.
Aquí está la clase base:
<?php
class Application_Form_Base extends Zend_Form
{
/** @var array Decorators to use for standard form elements */
// these will be applied to our text, password, select, checkbox and radio elements by default
public $elementDecorators = array(
''ViewHelper'',
''Errors'',
array(''Description'', array(''tag'' => ''p'', ''class'' => ''description'')),
array(''HtmlTag'', array(''class'' => ''form-div'')),
array(''Label'', array(''class'' => ''form-label'', ''requiredSuffix'' => ''*''))
);
/** @var array Decorators for File input elements */
// these will be used for file elements
public $fileDecorators = array(
''File'',
''Errors'',
array(''Description'', array(''tag'' => ''p'', ''class'' => ''description'')),
array(''HtmlTag'', array(''class'' => ''form-div'')),
array(''Label'', array(''class'' => ''form-label'', ''requiredSuffix'' => ''*''))
);
/** @var array Decorator to use for standard for elements except do not wrap in HtmlTag */
// this array gets set up in the constructor
// this can be used if you do not want an element wrapped in a div tag at all
public $elementDecoratorsNoTag = array();
/** @var array Decorators for button and submit elements */
// decorators that will be used for submit and button elements
public $buttonDecorators = array(
''ViewHelper'',
array(''HtmlTag'', array(''tag'' => ''div'', ''class'' => ''form-button''))
);
public function __construct()
{
// first set up the $elementDecoratorsNoTag decorator, this is a copy of our regular element decorators, but do not get wrapped in a div tag
foreach($this->elementDecorators as $decorator) {
if (is_array($decorator) && $decorator[0] == ''HtmlTag'') {
continue; // skip copying this value to the decorator
}
$this->elementDecoratorsNoTag[] = $decorator;
}
// set the decorator for the form itself, this wraps the <form> elements in a div tag instead of a dl tag
$this->setDecorators(array(
''FormElements'',
array(''HtmlTag'', array(''tag'' => ''div'', ''class'' => ''form'')),
''Form''));
// set the default decorators to our element decorators, any elements added to the form
// will use these decorators
$this->setElementDecorators($this->elementDecorators);
parent::__construct();
// parent::__construct must be called last because it calls $form->init()
// and anything after it is not executed
}
}
/*
Zend_Form_Element default decorators:
$this->addDecorator(''ViewHelper'')
->addDecorator(''Errors'')
->addDecorator(''Description'', array(''tag'' => ''p'', ''class'' => ''description''))
->addDecorator(''HtmlTag'', array(''tag'' => ''dd'',
''id'' => array(''callback'' => $getId)))
->addDecorator(''Label'', array(''tag'' => ''dt''));
*/
Ahora, para usar la clase, extienda todos sus formularios desde esta clase base y continúe asignando elementos de la forma habitual. Si usa Zend_Form_Element_XXX
en lugar de addElement()
, deberá pasar uno de los decoradores como una opción al constructor del elemento, si usa Zend_Form-> addElement, entonces usará el decorador predeterminado $elementDecorators
que le asignamos en la clase .
Aquí hay un ejemplo que muestra cómo extender desde esa clase:
<?php
class Application_Form_Test extends Application_Form_Base
{
public function init()
{
// Add a text element, this will automatically use Application_Form_Base->elementDecorators for its decorators
$this->addElement(''text'', ''username'', array(
''label'' => ''User Name:'',
''required'' => false,
''filters'' => array(''StringTrim''),
));
// This will not use the correct decorators unless we specify them directly
$text2 = new Zend_Form_Element_Text(
''text2'',
array(
''decorators'' => $this->elementDecorators, // must give the right decorator
''label'' => ''Text 2''
)
);
$this->addElement($text2);
// add another element, this also uses $elementDecorators
$this->addElement(''text'', ''email'', array(
''label'' => ''Email:'',
''required'' => false,
''filters'' => array(''StringTrim'', ''StringToLower''),
));
// add a submit button, we don''t want to use $elementDecorators, so pass the button decorators instead
$this->addElement(''submit'', ''submit'', array(
''label'' => ''Continue'',
''decorators'' => $this->buttonDecorators // specify the button decorators
));
}
}
Esto muestra una manera bastante efectiva de deshacerse de los elementos dd / dt y dl y reemplazarlos por los suyos. Es un poco incómodo tener que especificar los decoradores para cada elemento, en lugar de poder asignar decoradores a elementos específicos, pero parece que funciona bien.
Para agregar una solución más que creo que estabas buscando hacer, si quieres renderizar un elemento sin etiqueta, simplemente crea un nuevo decorador y omite el decorador de etiquetas de esta manera:
$elementDecorators = array(
''ViewHelper'',
''Errors'',
array(''Description'', array(''tag'' => ''p'', ''class'' => ''description'')),
array(''HtmlTag'', array(''class'' => ''form-div'')),
// array(''Label'', array(''class'' => ''form-label'', ''requiredSuffix'' => ''*''))
// comment out or remove the Label decorator from the element in question
// you can do the same for any of the decorators if you don''t want them rendered
);
Siéntase libre de pedir aclaraciones sobre cualquier cosa, con suerte esto lo ayudará.
Puede deshabilitar decoradores a nivel de formulario como este.
$form->setElementDecorators($decorators);
Esto eliminará los decoradores predeterminados y configurará los decoradores en $decorators
array como decoradores. Si desea eliminar selectivamente decoradores, debe considerar la implementación de este método y crear uno similar para eliminar decoradores.
Si desea desactivar ciertos decoradores para todos sus formularios, cree una clase Your_Form
que amplíe Zend_Form
y elimine esos decoradores en Your_Form
y amplíe todos los formularios de esta clase o simplemente cree instancias de esta clase.
Utilizar esta:
foreach ($this->getElements() as $element) {
$decorator = $element->getDecorator(''label'');
if (!$decorator) {
continue;
}
$decorator->removeOption(''tag'');
}
prueba esto:
foreach ($form->getElements() as $element) {
$element->removeDecorator(''DtDdWrapper'')
->removeDecorator(''HtmlTag'')
->removeDecorator(''Label'');
}
o
foreach ($form->getElements() as $element) {
$element->clearDecorators();
}