2010-11-16 8 views
10

sé que puedo retirar el material extra de cada elemento de forma individual como de maneraCómo quitar todos los DtDdWrappers y etiquetas en elementos de formulario Zend

$button ->removeDecorator('DtDdWrapper') 
     ->removeDecorator('HtmlTag') 
    ->removeDecorator('Label'); 

Me preguntaba si puedo conseguir el mismo para todos mis elementos en una forma zend?
¿Y cómo se elimina el dl envolviendo el formulario?

+0

después de pasar 250 representante de su pregunta, tal vez se podría aceptar el convite respuesta dada por drew010! – markus

Respuesta

25

Markus, aquí es una solución que utilizo que parece funcionar bien, espero que sea adecuado para usted.

En primer lugar, para representar el formulario sin la etiqueta <dl>, debemos configurar los decoradores en el objeto de formulario. Desde dentro de una clase que extiende Zend_Form, deberías llamar al Zend_Form->setDecorators() pasando una serie de decoradores de formularios.

Desde 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 la forma en algo más que un dl, utilizamos los decoradores anteriores, pero cambiamos el dl a cualquier etiqueta que utiliza, normalmente utilizo un div de la clase form 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 su propio conjunto de decoradores: [Botón Enviar &], [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 del formulario, texto, contraseña, seleccionar, casilla de verificación, etc. utilizan el mismo conjunto de decoradores predeterminados.

Para eliminar las etiquetas dd/dt de un elemento de formulario individual, necesitaríamos aplicarle nuestro propio conjunto de decoradores. Este es un ejemplo que no utiliza 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 envolver cada elemento de 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 tener bastante Zend_Form asignar automáticamente los decoradores correctas a los tipos de elementos específicos (se puede asignarlos a los nombres de elemento específico ), podemos establecer un valor predeterminado, y nos permiten acceder fácilmente a los decoradores de una colocar, por lo que si necesitan cambiar, se pueden cambiar fácilmente para todas las formas.

Aquí es 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 se utiliza la clase, se extienden todas sus formas de esta clase base y seguir con los elementos como de costumbre asignar. Si usa Zend_Form_Element_XXX en lugar de addElement(), deberá pasar uno de los decoradores como opción al constructor del elemento, si utiliza Zend_Form-> addElement, entonces usará el decorador predeterminado $elementDecorators que le asignamos en la clase.

Aquí es un ejemplo que muestra cómo extender de 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 forma bastante eficaz para deshacerse de los elementos dd/dt y dl y reemplazarlos con el suyo propio. 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 añadir una solución más que creo que estabas buscando para hacer, si le gustaría hacer que un elemento sin etiqueta, basta con crear un nuevo decorador y omitir el decorador de la etiqueta 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 
); 

No dude en pedir aclaraciones sobre cualquier cosa, con suerte esto lo ayudará.

+1

¡Muchas gracias por poner un poco de esfuerzo en esto! ¡Gran respuesta! – markus

4

Puede deshabilitar decoradores a nivel de formulario de esta manera.

$form->setElementDecorators($decorators); 

Esto eliminará los decoradores por defecto y establece los decoradores en $decorators matriz como los 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 todas sus formas, cree una clase que se extiende Your_FormZend_Form y quitar esos decoradores de Your_Form y extender todas sus formas de esta clase o simplemente crear instancias de esta clase.

+1

También se puede usar 'setDisableLoadDefaultDecorators()' para deshabilitar la carga de decoradores predeterminados – Gordon

+0

@Gordon Esto no elimina todas las etiquetas. – markus

+0

¡Esta respuesta NO aborda el problema de los contenedores en el formulario en sí! Además, tiene que haber una solución que permita eliminar TODOS los decoradores sin configurar ninguno personalizado. – markus

2

Los siguientes 4 líneas de código para mí

$elements = $this->getElements(); 
     foreach($elements as $element) { 
      $element->removeDecorator('DtDdWrapper') 
      ->removeDecorator('HtmlTag') 
      ->removeDecorator('Label'); 
     } 

preciosas

+0

¡Esta respuesta NO aborda el problema de los contenedores en el formulario mismo! Además, esto eliminará los textos de las etiquetas que sean necesarios. – markus

+0

bueno, entiendes la idea – droope

+1

Me ayudó. :) –

0

probar esto:

foreach ($form->getElements() as $element) { 
    $element->removeDecorator('DtDdWrapper') 
     ->removeDecorator('HtmlTag') 
     ->removeDecorator('Label'); 
} 

o

foreach ($form->getElements() as $element) { 
    $element->clearDecorators(); 
} 
2

Creo que la única manera de hacer esto es extender Zend_Form y luego overide los loadDefaultDecorators() y render() funciona 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 todavía será un poco incómodo ya que la función nueva render() se tira de las etiquetas que ha añadido a sus 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 la de muchos otros desarrolladores que utilizan Zend_Form no debe haber etiquetas en forma de marcado por defecto que no sea <form>, <input> y <label> etiquetas. El desarrollador puede agregar cualquier otra cosa con los métodos existentes.

1

Conseguir un poco tarde en el 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'); 
     }; 
    }; 
}; 
0

Utilice esta:

foreach ($this->getElements() as $element) { 
     $decorator = $element->getDecorator('label'); 
     if (!$decorator) { 
      continue; 
     } 
     $decorator->removeOption('tag'); 
    } 
Cuestiones relacionadas