Маркус, вот решение, которое я использую, которое, кажется, работает хорошо, надеюсь, оно подойдет вам.
Во-первых, для рендеринга формы без тега <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 автоматически назначал правильные декораторы определенным типам элементов (вы можетеназначив их конкретному элементу names ), мы можем установить значение по умолчанию и предоставить нам легкий доступ к декораторам из одного места, поэтому, если их нужно изменить, их можно легко изменить для всех форм.
Вот базовый класс:
<?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
);
Не стесняйтесь просить разъяснений по любому вопросу, надеюсьэто поможет вам.