Wie

2010-11-16 10 views
10

Alle DtDdWrappers und Labels auf Zend Form Elemente entfernen Ich weiß, dass ich das Extramaterial von jedem Element einzelnWie

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

Ich habe mich gefragt, ob ich in ein entfernen kann, wie so das gleiche für alle meine Elemente erreichen können Zend Form?
Und wie entfernt man die dl das Formular umschließt?

+0

nachdem ich verbrachte 250 rep auf Ihre Frage, vielleicht könnten Sie die Behandlung Antwort akzeptieren gegeben von draw010! – markus

Antwort

25

Markus, hier ist eine Lösung, die ich benutze das scheint gut zu funktionieren, hoffentlich wird es für Sie geeignet sein.

Erstens, um das Formular ohne <dl>-Tag zu rendern, müssen wir die Dekoratoren auf Formularobjekt selbst festlegen. Von einer Klasse, die Zend_Form erweitert, würden Sie Zend_Form->setDecorators() aufrufen und ein Array von Formular-Dekoratoren übergeben.

Aus dem Referenzhandbuch:

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' 
)); 

Um das Formular in etwas anderes als ein dl zu wickeln, verwenden wir die oben Dekorateure aber das dl ändern, was auch immer Tag, das Sie verwenden, ich in der Regel verwenden eine div der Klasse form, die wir später sehen werden.

Als nächstes müssen die Elemente behandelt werden. Zend_Form Elemente haben verschiedene Dekoratoren für verschiedene Arten von Elementen. Die folgenden Gruppen von Elementtypen haben jeweils einen eigenen Satz von Dekoratoren: [Senden & Schaltfläche], [Captcha], [Datei], [Bild] und [Radio *]. Der Dekorator für Radio ist den Standardelementen sehr ähnlich, außer dass er das for Attribut innerhalb des Etiketts nicht angibt.

Alle anderen Formularelemente, Text, Passwort, Auswahl, Kontrollkästchen, usw. verwenden den gleichen Satz von Standard-Dekoratoren.

Um die dd/dt-Tags von einem einzelnen Formularelement zu entfernen, müssten wir unsere eigenen Dekoratoren darauf anwenden. Hier ist ein Beispiel, das nicht dd/dt-Tags nicht verwendet:

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

Dieser wird jedes Formularelement in einem div-Tag mit der Klasse form-div wickelt. Das Problem ist, dass Sie diesen Satz von Dekoratoren auf jedes Element anwenden müssen, das nicht in die dd/dt-Tags eingeschlossen werden soll, was ein wenig problematisch sein kann.

Um dieses Problem zu lösen, erstelle ich eine Klasse, die von Zend_Form ausgeht und ihr ein Standardverhalten und Dekoratoren gibt, die sich von den Standard-Dekoratoren für Zend_Form unterscheiden.

Wir können zwar nicht ganz Zend_Form automatisch die richtigen Dekorateure auf bestimmte Elementtypen zuordnen (Sie können sie auf bestimmte Element zuweisen Namen), können wir einen Standard gesetzt, und geben uns einen einfachen Zugang zu den Dekorateure von einem Wenn sie sich ändern müssen, können sie leicht für alle Formen geändert werden. Hier

ist die Basisklasse:

<?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')); 
*/ 

nun die Klasse zu verwenden, erweitern Sie alle Ihre Formen von dieser Basisklasse und gehen über Elemente wie gewohnt zuweisen. Wenn Sie Zend_Form_Element_XXX im Gegensatz zu addElement() verwenden, müssen Sie einen der Dekoratoren als eine Option an den Elementkonstruktor übergeben, wenn Sie Zend_Form-> addElement verwenden, dann wird der Standarddecorator $elementDecorators verwendet, den wir in der Klasse zugewiesen haben. Hier

ist ein Beispiel, das zeigt, wie aus dieser Klasse erweitern:

<?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 
     )); 
    } 
} 

Dies zeigt einen ziemlich effektiven Weg, um loszuwerden, die dd/dt und dl-Elemente und ersetzen Sie sie mit Ihrem eigenen. Es ist ein wenig unpraktisch, die Dekoratoren für jedes Element angeben zu müssen, anstatt Dekoratoren bestimmten Elementen zuordnen zu können, aber das scheint gut zu funktionieren.

Um eine weitere Lösung hinzufügen, dass ich glaube, Sie zu tun suchen, wenn Sie ohne Etikett ein Element machen möchten, einfach einen neuen Dekorateur schaffen und die Labeldekorator aus es wie folgt weglassen:

$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 
); 

Fühlen Sie sich frei zu fragen, um etwas zu klären, hoffentlich wird dies Ihnen helfen.

+1

Vielen Dank für die Mühe! Gute Antwort! – markus

4

Sie können Dekoratoren auf Formularebene wie folgt deaktivieren.

$form->setElementDecorators($decorators); 

Dies wird die Standarddekorator und setzt die Dekoratore in $decorators Array als Dekoratore entfernen. Wenn Sie Dekoratoren selektiv entfernen möchten, sollten Sie in die Implementierung dieser Methode schauen und eine ähnliche zum Entfernen von Dekoratoren erstellen.

Wenn Sie alle Ihre Formen bestimmte Dekorateure für deaktivieren möchten, erstellen Sie eine Klasse, die Your_FormZend_Form und entfernen Sie diese Dekorateure auf Your_Form und erstrecken sich alle Formen von dieser Klasse oder einfach erstellen Instanzen dieser Klasse erweitert.

+1

Kann 'setDisableLoadDefaultDecorators()' auch verwenden, um das Laden von Standard-Dekoratoren zu deaktivieren – Gordon

+0

@Gordon Dies entfernt nicht alle Tags. – markus

+0

Diese Antwort adressiert nicht das Problem der Wrapper auf dem Formular selbst! Außerdem muss es eine Lösung geben, die ALLE Dekorierer einfach entfernen lässt, ohne irgendwelche benutzerdefinierten zu setzen. – markus

2

Die folgenden vier Codezeilen Arbeit für mich

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

Schöne

+0

Diese Antwort adressiert nicht das Problem der Wrapper auf dem Formular selbst! Außerdem werden dadurch notwendige Texte entfernt. – markus

+0

und Sie bekommen die Idee – droope

+1

Es hat mir geholfen. :) –

0

versuchen Sie dies:

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

oder

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

Ich denke, der einzige Weg, dies zu tun, ist Zend_Form zu erweitern und dann die loadDefaultDecorators overide() und render() funktioniert wie folgt. Sehen Sie, ob das für Sie funktioniert.

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; 
    } 
} 

Edit:

Ich denke, dass diese Methode noch etwas unbequem sein wird als die neue render() Funktion alle Tags Streifen werden Sie zu Ihrem Elemente hinzugefügt haben. Um dies zu umgehen, müssten Sie Zend_Form_Element erweitern und seine loadDefaultDecorators() -Methode auf die gleiche Weise überschreiben, wie ich es hier für das Formular getan habe.

Meiner Meinung nach, und wahrscheinlich die viele anderen Entwickler, die mit Zend_Form es sollte standardmäßig anders als <form>, <input> und <label> Tags keine Tags in Form Markup sein. Alles andere kann vom Entwickler mit vorhandenen Methoden hinzugefügt werden.

1

Erste ein wenig zu spät in den Thread, aber es funktionierte für mich

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

verwenden:

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