Как удалить все DtDdWrappers и метки на элементах формы Zend
Я знаю, что могу удалить лишнее вещество из каждого элемента по отдельности, как это
$button ->removeDecorator('DtDdWrapper')
->removeDecorator('HtmlTag')
->removeDecorator('Label');
Мне было интересно, могу ли я достичь того же для всех моих элементов в форме zend?И как можно удалить dl, обертывающий форму?
7 ответов:
Маркус, вот решение, которое я использую, которое, кажется, работает хорошо, надеюсь, что оно будет подходящим для вас.
Во-первых, чтобы отобразить форму без тега<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 к любому тегу, который вы используете, я обычно использую
div
классаform
, который мы увидим позже.Далее необходимо разобраться с элементами. Элементы Zend_Form имеют различные декораторы для различных типов элементов. Следующие группы типов элементов имеют свой собственный набор декораторов: [Submit & Button], [Captcha], [File], [Image] и [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
, назначенный в класс.Вот пример, который показывает, как расширить из этого класса:
Это показывает довольно эффективный способ избавиться от элементов dd/dt и dl и заменить их своими собственными. Это немного неудобно, чтобы указать декораторов для каждого элемента, в отличие от возможности назначить декораторов для конкретных элементов, но это, кажется, работает хорошо.<?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 )); } }
Чтобы добавить еще одно решение, которое, я думаю, вы хотели бы сделать, если вы хотите отрисовать элемент без ярлыка просто создайте новый декоратор и опустите из него ярлык декоратора следующим образом:
Не стесняйтесь обращаться за разъяснениями по любому вопросу, надеюсь, это поможет вам.$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 );
Вы можете отключить декораторы на уровне формы, как это.
$form->setElementDecorators($decorators);
Это удалит декораторы по умолчанию и установит декораторы в массиве
$decorators
в качестве декораторов. Если вы хотите выборочно удалить декораторы, вам следует изучить реализацию этого метода и создать аналогичный для удаления декораторов.Если вы хотите отключить определенные декораторы для всех ваших форм, создайте класс
Your_Form
, который расширяетZend_Form
и удалите эти декораторы наYour_Form
и расширьте все ваши формы. формирует из этого класса или просто создает экземпляры этого класса.
Следующие 4 строки кода работают для меня
$elements = $this->getElements(); foreach($elements as $element) { $element->removeDecorator('DtDdWrapper') ->removeDecorator('HtmlTag') ->removeDecorator('Label'); }
Прекрасный
Я думаю, что единственный способ сделать это-расширить 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; } }
Редактировать:
Я думаю, что этот метод все еще будет немного неудобен, так как новая функция render() очистит все теги, которые вы добавили к своим элементам. Чтобы обойти это, вам нужно будет расширить Zend_Form_Element и переопределить его метод loadDefaultDecorators() таким же образом как я сделал здесь для формы.
На мой взгляд, и, вероятно, что многих других разработчиков, использующих Zend_Form, в разметке формы по умолчанию не должно быть никаких тегов, кроме
<form>
,<input>
и<label>
теги. Все остальное может быть добавлено разработчиком с помощью существующих методов.
Немного запоздал в потоке, но это сработало для меня
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' ); }; }; };