2010-11-16 36 views
10

我知道我可以從每個元素單獨刪除多餘的東西,像這樣如何在Zend的表單元素刪除所有DtDdWrappers和標籤

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

我在想,如果我能實現我的所有元素相同zend表單?
如何刪除包裝表單的dl?

+0

後,我花了250代表你的問題,也許你可以接受給出的治療答案通過drew010! – markus 2011-11-11 11:40:24

回答

25

馬庫斯,這裏是我使用似乎運作良好的解決方案,希望這將是適合你的。

首先,爲了渲染沒有<dl>標記的表單,我們需要在表單對象本身上設置裝飾器。從擴展Zend_Form的類中,您可以調用Zend_Form->setDecorators()傳遞一個表單裝飾器數組。

從參考指南:

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

來包裝形式比DL以外的東西,我們用上面的裝飾,但改變DL對任何標記你用,我通常使用類formdiv,我們將在稍後看到。

接下來,需要處理這些元素。對於不同類型的元素,Zend_Form元素具有不同的裝飾器。以下幾組元素類型每個都有自己獨特的一組裝飾器:[Submit & Button,[Captcha],[File],[Image]和[Radio *]。 radio的裝飾器與標準元素非常相似,只是它沒有在標籤內指定for屬性。

所有其他表單元素,文本,密碼,選擇,複選框等都使用同一組默認裝飾器。

要從單個表單元素中刪除dd/dt標籤,我們需要將我們自己的一組裝飾器應用到它。這裏是不使用DD/dt的標記的示例:

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

這將包裹每個表單元素在div標籤與類form-div。問題是,你必須將這組裝飾器應用到每個你不想被包裝在dd/dt標籤中的元素,這可能會有點問題。

爲了解決這個問題,我創建了一個從Zend_Form擴展的類,並給它一些默認的行爲和裝飾器,它們與Zend_Form的默認裝飾器不同。雖然我們不太可能有Zend_Form自動將正確的裝飾器分配給特定的元素類型(您可以將它們分配給特定元素名稱),但我們可以設置一個默認值,並讓我們可以輕鬆地從一個元素中訪問裝飾器所以如果他們需要改變,他們可以很容易地改變爲所有形式。

這是基礎類:

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

現在使用的類,延長您的所有形式,從這個基類和去分配的元素如常。如果你使用Zend_Form_Element_XXX而不是addElement()那麼你需要將一個裝飾器作爲選項傳遞給元素構造器,如果你使用Zend_Form-> addElement,那麼它將使用我們在類中分配的默認裝飾器$elementDecorators

這裏展示瞭如何從該類擴展的例子:

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

這表明爲了擺脫DD/dt和DL元素,並用自己取代他們一個非常有效的方法。必須爲每個元素指定裝飾器有點不方便,而不是能夠將裝飾器分配給特定的元素,但這似乎工作得很好。

多加一個解決方案,我認爲你正在尋找做,如果你想使一個元素,沒有標籤,只需創建一個新的裝飾,並從中省略標籤裝飾是這樣的:

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

隨時要求澄清任何事情,希望這會幫助你。

+1

非常感謝您付出一些努力!很好的答案! – markus 2011-10-07 06:09:33

4

您可以像這樣在表單級禁用裝飾器。

$form->setElementDecorators($decorators); 

這將刪除缺省的裝飾,並設置在裝飾$decorators陣列作爲裝飾。如果你想有選擇地移除裝飾器,你應該看看這個方法的實現,並創建一個類似的去除裝飾器。

如果您想爲您的所有形式的禁用某些裝飾,創建一個類Your_Form擴展Zend_Form和刪除Your_Form這些裝飾和擴大從該課程的所有形式或簡單地創建該類的實例。

+1

也可以使用'setDisableLoadDefaultDecorators()'來禁用加載默認裝飾器 – Gordon 2010-11-16 08:42:55

+0

@Gordon這不會刪除所有標籤。 – markus 2011-10-02 22:13:59

+0

這個答案沒有解決窗體本身的包裝問題!此外,必須有一個解決方案,只需刪除所有裝飾器而不設置任何自定義裝飾器。 – markus 2011-10-02 22:19:26

2

以下4行代碼的工作對我來說

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

可愛

+0

這個答案不能解決表單本身的包裝問題!此外,這將刪除必要的標籤文本。 – markus 2011-10-02 22:19:51

+0

好吧,你有想法 – droope 2011-10-03 16:00:02

+1

它幫助了我。 :) – 2012-08-06 16:47:57

0

試試這個:

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

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

我想這樣做的唯一方法是延長Zend_Form的,然後在此改變是loadDefaultDecorators()和render()函數如下。看看這是否適合你。

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

編輯:

我認爲這個方法仍然會稍顯不便作爲新的渲染()函數將去除您已經添加到您的元素的任何標記。爲了解決這個問題,你需要擴展Zend_Form_Element並覆蓋它的loadDefaultDecorators()方法,就像我在表單中完成的那樣。

在我看來,也許很多其他開發人員使用Zend_Form應該沒有標籤的默認形式標記除<form>,<input><label>標籤。開發人員可以使用現有方法添加任何其他內容。

1

變得有點晚了線程,但它爲我工作

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

使用此:

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