У меня есть 2 требования: 1) Все скрытые элементы ввода должны быть затронуты без удаления стандартных декораторов. 2) Это должно произойти без необходимости указывать его для каждого элемента.
Все, что мне нужно, – это привязать класс CSS к тегам DT & DD, если тип элемента – Zend_Form_Element_Hidden.
Я пробовал создавать пользовательские декодеры HtmlTag, DtDdWrapper и FormElement, но не смог понять, как это сделать.
По умолчанию они отображаются следующим образом:
<dt> </dt> <dd><input type="hidden" name="whatever" value="bling" /></dd>
Я бы хотел, чтобы они выглядели следующим образом:
<dt class="hidden"> </dt> <dd class="hidden"><input type="hidden" name="whatever" value="bling" /></dd>
Таким образом, они все равно будут там, где они должны быть, но они не будут прерывать поток документа.
Пример того, что не сработало:
class My_Form_Decorator_DtDdWrapper extends Zend_Form_Decorator_DtDdWrapper { public function render($content) { if ($this->getElement() instanceof Zend_Form_Element_Hidden) { return '<dt class="hidden"> </dt><dd class="hidden">'.$content.'</dd>'; } else { return parent::render($content); } }
На основе вашего желаемого результата выборки я не понимаю, почему вы хотели бы включить <dt>
в скрытые элементы, тем более, что вы не применяете какой-либо ярлык, они становятся ненужной разметкой. Исходя из предположения, что этикетка не нужна , вы можете добиться желаемого эффекта со следующим:
class TestForm extends Zend_Form { protected $_hiddenElementDecorator = array( 'ViewHelper', array('HtmlTag', array('tag' => 'dd', 'class' => 'hidden')), ); public function init() { $this->addElement('hidden', 'hiddenElement0'); $element = new Zend_Form_Element_Hidden('hiddenElement1'); $this->addElement($element); } public function loadDefaultDecorators() { foreach ($this->getElements() as $element) { if ($element->getType() === "Zend_Form_Element_Hidden") { $element->setDecorators($this->_hiddenElementDecorator); } } parent::loadDefaultDecorators(); } }
Оба из этих элементов приведут к тому же выводу с их соответствующими идентификаторами. Пример:
<dd class="hidden"> <input type="hidden" name="hiddenElement0" value="" id="hiddenElement0" /> </dd>
Цикл foreach
в loadDefaultDecorators()
итеративно применяет $this->_hiddenElementDecorator
к каждому скрытому элементу формы, когда форма построена. Если вы хотите применить декоратор скрытых элементов на нескольких формах, просто создайте родительский класс с переменной $_hiddenElementDecorator
и loadDefaultDecorators()
.
Тем не менее, если вы настроили свое сердце, включая элемент метки ( <dt>
), как описано в вашем примере вывода, и применяете «скрытый» класс, чтобы в итоге получилось:
<dt class="hidden"> </dt> <dd class="hidden"> <input type="hidden" name="hiddenElement0" value="" id="hiddenElement0" /> </dd>
… вам нужно будет расширить класс Zend_Form_Decorator_Label
и переопределить метод render (). Взгляните на комментарий в блоке if (null !== $tag)
:
class My_Form_Decorator_Label extends Zend_Form_Decorator_Label { public function render($content) { $element = $this->getElement(); $view = $element->getView(); if (null === $view) { return $content; } $label = $this->getLabel(); $separator = $this->getSeparator(); $placement = $this->getPlacement(); $tag = $this->getTag(); $id = $this->getId(); $class = $this->getClass(); $options = $this->getOptions(); if (empty($label) && empty($tag)) { return $content; } if (!empty($label)) { $options['class'] = $class; $label = $view->formLabel($element->getFullyQualifiedName(), trim($label), $options); } else { $label = ' '; } if (null !== $tag) { require_once 'Zend/Form/Decorator/HtmlTag.php'; $decorator = new Zend_Form_Decorator_HtmlTag(); // Add 'class' => 'hidden' to the <dt> tag decorator options. $decorator->setOptions(array('tag' => $tag, 'class' => 'hidden')); $label = $decorator->render($label); } switch ($placement) { case self::APPEND: return $content . $separator . $label; case self::PREPEND: return $label . $separator . $content; } } }
Наконец, чтобы применить ваш новый декоратор ко всем элементам скрытой формы, вам нужно будет добавить точку пути префикса элемента к вашему декоратору и снова добавить декоратор $_hiddenElementDecorator
массив $_hiddenElementDecorator
в классе TestForm
:
class TestForm extends Zend_Form { protected $_hiddenElementDecorator = array( 'ViewHelper', array('HtmlTag', array('tag' => 'dd', 'class' => 'hidden')), // Add back the label element. array('Label', array('tag' => 'dt', 'class' => 'hidden')), ); public function init() { $this->addElement('hidden', 'hiddenElement0'); $element = new Zend_Form_Element_Hidden('hiddenElement1'); $this->addElement($element); } public function loadDefaultDecorators() { foreach ($this->getElements() as $element) { if ($element->getType() === "Zend_Form_Element_Hidden") { $element->setDecorators($this->_hiddenElementDecorator); } } // Add a decorator prefix path pointing to our new nifty decorator. $this->addElementPrefixPath('My_Form_Decorator', '/path/to/Decorator', Zend_Form_Element::DECORATOR); parent::loadDefaultDecorators(); } }
Легко, как пирог, нет?
Это поможет вам: вы также можете указать любые другие атрибуты.
$el = $form->getElement('whatever'); $el->addDecorators( array('ViewHelper', array('HtmlTag',array('tag' => 'dt','class'=>'hidden')), array('Label', array('tag' => 'dd ', 'class'=>'hidden')), ));