2010-11-16 8 views
10

wiem, że mogę usunąć dodatkowy materiał z każdego elementu indywidualnie jak takJak usunąć wszystkie DtDdWrappers i etykiety na Zend Form Elements

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

Zastanawiałem się, czy mogę osiągnąć takie same dla wszystkich moich elementów w Zend Form?
A jak usunąć dl zawijający formularz?

+0

po spędziłem 250 rep na swoje pytanie, być może można było przyjąć odpowiedź traktować daną przez drew010! – markus

Odpowiedz

25

Markus, tutaj jest to rozwiązanie, które używam, który wydaje się działać dobrze, mam nadzieję, że to będzie odpowiedni dla Ciebie.

Po pierwsze, aby renderować formularz bez tagu <dl>, musimy ustawić dekoratory na samym obiekcie formularza. Od wewnątrz klasy rozszerzającej Zend_Form, nazwałbyś Zend_Form->setDecorators() przekazując tablicę dekoratorów formularzy.

Od poradnik:

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

owinąć formę w coś innego niż dl, używamy powyższe dekoratorów ale zmienić dl do jakiegokolwiek tagu użyć, ja zazwyczaj korzystają a div klasy form, którą zobaczymy później.

Następnie należy zająć się pierwiastkami. Elementy Zend_Form mają różne dekoratory dla różnych typów elementów. Następujące grupy typów elementów mają swój własny, odrębny zestaw dekoratorów: [Wyślij: & Przycisk], [Captcha], [Plik], [Obrazek] i [Radio *]. Dekorator radia jest bardzo podobny do standardowych elementów, z tym że nie określa atrybutu for wewnątrz etykiety.

Wszystkie inne elementy formularza, tekst, hasło, zaznacz, pole wyboru itp używają tego samego zestawu domyślnych dekoratorów.

Aby usunąć znaczniki dd/dt z pojedynczego elementu formularza, należy zastosować do niego własny zestaw dekoratorów. Poniżej przedstawiono przykład, który nie wykorzystuje znaczniki, dd/dt:

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

to zawinie każdy element formy w znaczniku div z klasą form-div. Problem polega na tym, że musisz zastosować ten zestaw dekoratorów do KAŻDEGO elementu, którego nie chcesz zawijać w znaczniki dd/dt, co może być nieco problematyczne.

Aby rozwiązać ten problem, tworzę klasę, która rozciąga się od Zend_Form i nadaje mu domyślne zachowanie i dekoratory, które różnią się od domyślnych dekoratorów dla Zend_Form.

Chociaż nie możemy całkiem Zend_Form automatycznie przypisać poprawne dekoratory do konkretnych typów elementów (można przypisać je do konkretnego elementu nazwy), możemy ustawić domyślne i dać sobie łatwy dostęp do dekoratorów z jednego miejsce, więc jeśli muszą się zmienić, można je łatwo zmienić dla wszystkich form.

Oto klasa bazowa:

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

Teraz użyć klasy przedłużyć wszystkich swoich postaciach z tej klasy bazowej i iść o przypisywanie elementy jak zwykle. Jeśli użyjesz Zend_Form_Element_XXX w przeciwieństwie do addElement(), będziesz musiał przekazać jeden z dekoratorów jako opcję do konstruktora elementów, jeśli użyjesz Zend_Form-> addElement, to użyje domyślnego dekoratora $elementDecorators, który mamy przypisany w klasie.

Oto przykład, który pokazuje, jak wychodzą z tej klasy:

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

Pokazuje to dość skuteczny sposób, aby pozbyć DD/dt i DL elementów i zastąpienie ich własne. Uciążliwe jest określanie dekoratorów dla każdego elementu, w przeciwieństwie do możliwości przypisywania dekoratorów do konkretnych elementów, ale wydaje się, że działa to dobrze.

Aby dodać jeszcze jedno rozwiązanie, które myślę, że szukałeś zrobić, jeśli chcesz, aby uczynić element bez etykiety, wystarczy utworzyć nowy dekorator i pominąć dekorator etykiety z nim tak:

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

Możesz poprosić o wyjaśnienie czegokolwiek, mam nadzieję, że to ci pomoże.

+1

Wielkie dzięki za włożenie w to trochę wysiłku! Świetna odpowiedź! – markus

4

Można wyłączyć dekoratory na poziomie formularza w ten sposób.

$form->setElementDecorators($decorators); 

To usunie domyślnych dekoratorów i ustawia dekoratorów w $decorators tablicy jako dekoratorów. Jeśli chcesz selektywnie usunąć dekoratory, powinieneś zajrzeć do implementacji tej metody i stworzyć podobną do usuwania dekoratorów.

Jeśli chcesz wyłączyć niektóre dekoratorów dla wszystkich swoich formach, należy utworzyć klasę Your_Form który rozciąga Zend_Form i usunąć te dekoratorów na Your_Form i rozszerzyć na wszystkie formy z tej klasy, lub po prostu tworzyć instancje tej klasy.

+1

Można również użyć polecenia 'setDisableLoadDefaultDecorators()', aby wyłączyć ładowanie domyślnych dekoratorów. – Gordon

+0

@Gordon Nie spowoduje to usunięcia wszystkich znaczników. – markus

+0

Ta odpowiedź NIE rozwiązuje problemu samych wrapperów na samym formularzu! Ponadto musi istnieć rozwiązanie, które pozwala usunąć WSZYSTKIE dekoratory bez ustawiania żadnych niestandardowych. – markus

2

następujące 4 linie kodu pracy dla mnie

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

Nostalgia

+0

Ta odpowiedź NIE rozwiązuje problemu owijaczy w samym formularzu! Ponadto usunie to niezbędne teksty etykiet. – markus

+0

Cóż, masz pomysł – droope

+1

Pomogło mi to. :) –

0

spróbuj tego:

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

lub

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

Myślę, że jedynym sposobem na osiągnięcie tego jest rozszerzenie Zend_Form a następnie overide z loadDefaultDecorators() i render() działa w następujący sposób. Sprawdź, czy to działa dla Ciebie.

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:

Myślę, że metoda ta nadal będzie nieco niewygodne jak render() funkcja nowy obetnie wszelkie znaczniki zostały dodane do listy elementów. Aby obejść ten problem, musisz rozszerzyć Zend_Form_Element i zastąpić jego metodę loadDefaultDecorators() w taki sam sposób, jak to zrobiłem tutaj dla formularza.

Moim zdaniem, i że prawdopodobnie wielu innych programistów korzystających z Zend_Form nie powinno być żadnych znaczniki w postaci znaczników domyślnie innego niż <form>, <input> i <label> tagów. Cokolwiek innego może zostać dodane przez programistę przy użyciu istniejących metod.

1

już trochę późno w wątku, ale pracował dla mnie

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

Użyj tego:

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