Zend更改验证错误行为:将元素包装在另一个标记中

jbl*_*lue 1 php zend-framework zend-form zend-validate

我为电子邮件设置了验证器,因此它不能为空.

这是zend_form生成的常用形式的标记:

<dt id="email-label"><label class="required" for="email">Email</label></dt>
<dd id="email-element">
   <input type="text" value="" id="email" name="email">
</dd>
Run Code Online (Sandbox Code Playgroud)

验证失败时,zend_form ul class="errors"在dd中添加一个新内容

<dt id="email-label"><label class="required" for="email">Email</label></dt>
<dd id="email-element">
   <input type="text" value="" id="email" name="email">
   <ul class="errors">
      <li>Value is required and can't be empty</li>
   </ul>
</dd>
Run Code Online (Sandbox Code Playgroud)

如何稍微更改此默认行为,以便整个dt dd包装在单个psomething我可以添加错误类?我的猜测是我需要指定zend_form在元素出错时如何表现.

rek*_*o_t 5

你可以创建自己的装饰器来做到这一点,像这样简单::

class My_Decorator_ElementWrapper extends Zend_Form_Decorator_Abstract
{
    public function render($content)
    {
        $class = 'form-element';
        $errors = $this->getElement()->getMessages();
        if (!empty($errors))
            $errors .= ' has-errors';
        return '<div class="'.$class.'">' . $content . '</div>';
    }
}
Run Code Online (Sandbox Code Playgroud)

现在你可以为元素注册这个装饰器:

$element->addPrefixPath('My_Decorator', 'My/Decorator/', 'decorator');
$element->addDecorator('ElementWrapper');
Run Code Online (Sandbox Code Playgroud)

您也可以使用$form->addElementPrefixPath()相反的方法同时注册所有元素的前缀路径.

如果你想为所有元素自动添加这个装饰器(和前缀路径),我建议你扩展每个元素Zend的相应元素(例如make make My_Form_Element_Textextends Zend_Form_Element_Text),然后在init函数中添加前缀路径,并覆盖loadDefaultDecorators()方法添加ElementWrapper装饰链的末尾.例如,这是如何loadDefaultDecorators()寻找Zend_Form_Element_Text:

public function loadDefaultDecorators()
{
    if ($this->loadDefaultDecoratorsIsDisabled()) {
        return $this;
    }

    $decorators = $this->getDecorators();
    if (empty($decorators)) {
        $this->addDecorator('ViewHelper')
            ->addDecorator('Errors')
            ->addDecorator('Description', array('tag' => 'p', 'class' => 'description'))
            ->addDecorator('HtmlTag', array('tag' => 'dd',
                                            'id'  => $this->getName() . '-element'))
            ->addDecorator('Label', array('tag' => 'dt'));
    }
    return $this;
}
Run Code Online (Sandbox Code Playgroud)

你只需->addDecorator('ElementWrapper')在链的末尾添加一个.所以要展示一个具体的例子My_Form_Element_Text:

class My_Form_Element_Text extends Zend_Form_Element_Text
{
    public function init()
    {
        $this->addPrefixPath('My_Decorator', 'My/Decorator/', 'decorator');
    }

    public function loadDefaultDecorators()
    {
        if ($this->loadDefaultDecoratorsIsDisabled()) {
            return $this;
        }

        $decorators = $this->getDecorators();
        if (empty($decorators)) {
            $this->addDecorator('ViewHelper')
                ->addDecorator('Errors')
                ->addDecorator('Description', array('tag' => 'p', 'class' => 'description'))
                ->addDecorator('HtmlTag', array('tag' => 'dd',
                                                'id'  => $this->getName() . '-element'))
                ->addDecorator('Label', array('tag' => 'dt'))
                ->addDecorator('ElementWrapper');
        }
        return $this;
    }
}
Run Code Online (Sandbox Code Playgroud)