Zend Framework 2 - Декораторы элементов форм
Я хочу форматировать форму Zend в стиле Twitter Bootstrap. Я в настоящее время перебираю поля формы и записываю информацию о форме в мою конструкцию div ботстрапа.
Я видел в Zend Framework 1 (!), что есть способ сделать это в декораторе. Но по какой-то причине документ для версии 2 не охватывает этот момент...
Я хотел бы сделать что-то вроде этого:
protected $_format = '<label for="%s">%s</label>'
. '<input id="%s" name="%s" type="text" value="%s"/>';
public function render($content)
{
$element = $this->getElement();
$name = htmlentities($element->getFullyQualifiedName());
$label = htmlentities($element->getLabel());
$id = htmlentities($element->getId());
$value = htmlentities($element->getValue());
$markup = sprintf($this->_format, $name, $label, $id, $name, $value);
return $markup;
}
Любые идеи?
Ответы
Ответ 1
Теперь я использую partials
. Я повторяю атрибуты, создаю несколько исключений, например, CSRF
и Submit
... Это работает довольно гладко:
Вид
echo $this->partial('partial/form-partial', array(
'form' => $this->form,
'url' => $this->url('whatever', array('action' => 'add')))); ?>
Частичная
<?php
$form = $this->form;
$form->setAttribute ( 'action', $this->url () );
$form->prepare ();
echo $this->form ()->openTag ( $form );
foreach ( $form as $element ) :
?>
<div
class="control-group <?php if($this->formElementErrors($element)) echo "error" ?>">
<label class="control-label"><?php echo $element->getLabel() ?></label>
<div class="controls">
<?php echo $this->formElement ( $element );
if ($this->formElementErrors ( $element ))
?>
<span class="help-inline"><?php echo $this->formElementErrors($element) ?></span>
</div>
</div>
<?php
endforeach;
echo $this->form ()->closeTag ( $form );
?>
Исключения исключены ради ясности...
Ответ 2
Я сделал это так, как сказал Рюфинус. См. Этот учебник о том, как создать просмотр помощников в ZF2 http://blog.evan.pro/creating-a-simple-view-helper-in-zend-framework-2
В моем случае я просто хотел обернуть элементы формы элементами списка, чтобы я расширил исходные справочные элементы ZF2 View, и пусть они выполняют рендеринг элементов. Я просто завернул то, что они вернут:
Просмотреть помощник FormCollection.php
<?php
// ./src/Application/View/Helper/FormCollection.php
namespace Application\View\Helper;
use Zend\Form\ElementInterface;
use Zend\Form\View\Helper\FormCollection as BaseFormCollection;
class FormCollection extends BaseFormCollection {
public function render(ElementInterface $element) {
return '<ul>'.parent::render($element).'</ul>';
}
}
Просмотреть помощник FormElement.php
<?php
// ./src/Application/View/Helper/FormElement.php
namespace Application\View\Helper;
use Zend\Form\ElementInterface;
use Zend\Form\View\Helper\FormElement as BaseFormElement;
class FormElement extends BaseFormElement {
public function render(ElementInterface $element) {
if ($element->getOption('required')) {
$req = 'required';
}
$type = $element->getAttribute('type');
$name = $element->getAttribute('name');
return sprintf('<li class="%s %s %s">%s</li>', $name, $req, $type, parent::render($element));
}
}
в то время как мое представление выглядит так и не нуждается в модификации, чтобы изменения вступили в силу.
<?php
$form = $this->form;
$form->prepare();
echo $this->form()->openTag($form);
echo $this->formCollection($form);
echo $this->form()->closeTag($form);
работал как шарм.
Ответ 3
Я попробовал метод Ron Partial, результат был бы таким, который не был предназначен для Bootstrap 3.
<form id="tea" name="tea" method="POST" action="/tea/add">
...
<div class="form-group">
<label class="control-label">Brand</label>
<div class="form-control">
<input type="text" value="" name="brand">
</div>
...
Мы знаем, что для использования предварительно заданного стиля формы bootstrap 3 нам нужно определить стиль для элемента ввода: form-control, а не его обертывающий элемент.
Мой частичный путь следующий.
echo $this->form()->openTag($form);
foreach ($form as $element) :?>
<div class="form-group">
<?php
if ($element->getOption('required')) { $req = 'required'; }
$type = $element->getAttribute('type');
$name = $element->getAttribute('name');
$label = $element->getLabel();
?>
<?php if ($name == 'id') { ?>
<div class="hidden"><?php echo $this->formElement($element); ?></div>
<?php } else if ($name == 'submit') { ?>
<input class='btn' name='submit' type='submit' value='Add'>
<?php } else if ($label != '') { ?>
<label class="control-label"><?php echo $label ?></label>
<input class='form-control' name='<?php echo $name ?>' type='<?php echo $type ?>'>
<?php } ?>
</div>
<?php
endforeach;
echo $this->form()->closeTag();
Ну, мы могли бы получить результат.
<form id="tea" name="tea" method="POST" action="/tea/add">
...
<div class="form-group">
<label class="control-label">Brand</label>
<input class="form-control" type="text" name="brand">
</div>
...
Как добавить пользовательские стили в формы zf2: добавить атрибут класса в элемент формы.
class TeaForm extends Form
{
public function __construct($name = null)
{
// we want to ignore the name passed
parent::__construct('tea');
$this->add(array(
'name' => 'id',
'type' => 'Hidden',
));
$this->add(array(
'name' => 'brand',
'type' => 'Text',
'options' => array(
'label' => 'Brand',
),
/** **define class attribute** **/
'attributes' => array(
'class' => 'form-control',
),
));
....
Это выглядит довольно просто, но проблема заключается в том, что элемент ввода будет обернут в элемент метки, который еще не предназначен для Bootstrap 3.
<form id="tea" role="form" name="tea" method="POST" action="/tea/add">
<input type="hidden" value="" name="id">
<label>
<span>Name</span>
<input class="form-control" type="text" value="" name="name">
</label>
...
По моему мнению, метод Partial по-прежнему является одним гибким и легким выбором. Tea Box - одна из практик ZF2, вы можете найти все вышеупомянутый код и описание из Gibhub
Ответ 4
Это упростит код.
http://php.net/manual/en/function.echo.php
<?php
$form->prepare();
echo
$this->form()->openTag($form),
$this->formCollection($form),
$this->form()->closeTag($form);