代码之家  ›  专栏  ›  技术社区  ›  Moak

如何删除zend表单元素上的所有dtddwrapper和标签

  •  10
  • Moak  · 技术社区  · 14 年前

    我知道我可以像这样从每个元素中单独删除多余的内容

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

    我想知道我是否可以以zend的形式为所有元素实现相同的结果?
    如何删除包装表单的DL?

    7 回复  |  直到 10 年前
        1
  •  25
  •   drew010    13 年前

    马库斯,这是一个我使用的解决方案,看起来效果很好,希望它会适合你。

    首先,为了呈现没有 <dl> 标记,我们需要在窗体对象本身上设置修饰符。从扩展zend_形式的类内部,您将调用 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更改为您使用的任何标记,我通常使用 div 阶级的 form 稍后我们将看到。

    接下来,需要处理元素。Zend_窗体元素对于不同类型的元素具有不同的装饰器。以下元素类型组各有自己独特的装饰器集:【提交&button】、【验证码】、【文件】、【图像】和【收音机*】。收音机的装饰器与标准元素非常相似,只是它没有指定 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_窗体的类,并为它提供一些不同于Zend_窗体的默认装饰器的默认行为和装饰器。

    虽然我们不能让Zend_窗体自动将正确的装饰器分配给特定的元素类型(您可以将它们分配给特定的元素) 姓名 )我们可以设置一个默认值,并让我们自己从一个地方轻松地访问装饰器,因此如果需要更改,可以轻松地为所有表单更改它们。

    下面是基类:

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

    请随时要求澄清任何问题,希望这能帮到你。

        2
  •  4
  •   Nithesh Chandra    14 年前

    您可以在这样的表单级别禁用装饰器。

    $form->setElementDecorators($decorators);
    

    这将删除默认的装饰器并将装饰器设置为 $decorators 数组作为装饰器。如果您希望有选择地移除装饰器,那么应该研究这个方法的实现,并创建一个类似的方法来移除装饰器。

    如果要禁用所有窗体的某些装饰器,请创建一个类 Your_Form 延伸的 Zend_Form 把那些装修工搬走 YouSype 并扩展这个类中的所有表单,或者简单地创建这个类的实例。

        3
  •  2
  •   Pedro    14 年前

    以下4行代码对我有效

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

    可爱的

        4
  •  2
  •   vascowhite    13 年前

    我认为这样做的唯一方法是扩展zend_窗体,然后按如下方式覆盖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;
        }
    }
    

    编辑:

    我认为这个方法仍然有点不方便,因为新的render()函数将删除您添加到元素中的所有标记。为了解决这个问题,您需要扩展zend_form_元素,并像我在这里为表单所做的那样,重写它的loadDefaultDecorators()方法。

    在我看来,可能还有其他许多使用zend_表单的开发人员,在表单标记中除了 <form> , <input> <label> 标签。开发人员可以使用现有方法添加任何其他内容。

        5
  •  1
  •   markcial    12 年前

    有点晚了,但对我有好处

    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' );
            };
        };
    };
    
        6
  •  0
  •   JellyBelly    13 年前

    试试这个:

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

    foreach ($form->getElements() as $element) {
        $element->clearDecorators();
    }
    
        7
  •  0
  •   MD66    10 年前

    使用此:

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