Использование ViewScript Decorator для вложенных подчиненных форм (Zend Form) - PullRequest
6 голосов
/ 29 сентября 2011

Я хочу использовать скрипт вида для визуализации моей Zend-формы, так как она кажется наилучшим способом управления макетом / дизайном формы при использовании классов Zend_Elements.

Из скрипта вида:Я отображаю элемент с $this->element->getElement('elementName').

У меня проблемы с именами элементов.На самом деле это подформа внутри подформы внутри формы.

Когда я использовал декораторы FormElements, полное имя элементов было form [subForm] [subForm] [element], которое былохорошо.Когда я перешел к декораторам viewScript, он изменился на subForm [subForm] [element].

Я понял, что мне нужно использовать декоратор PrepareElements, чтобы это исправить, но это заставило имя изменить форму [subForm][form] [subForm] [subForm] [elements] (он удвоил первые два имени в начале).

Есть идеи, как мне справиться с этим?

Спасибо.

ОБНОВЛЕНИЕ: Я попытался отладить PrepareElements, и я действительно не понимаю, что делает.Кажется, что он работает нормально в первой итерации, но затем он снова добавляет префикс формы [subform] при запуске на одной из средних подчиненных форм.

Когда я не использую декоратор PrepareElements, япросто отсутствует префикс «form» в именах (т. е. вместо form [subForm] [element] я получаю только subForm [element]).

Может быть, я могу это как-то исправить?

Я пытался изменить принадлежность, но это заменило только префикс "subForm".

На самом деле кажется, что отсутствует метод метод к элементу subForm.

СноваЭто все из-за декоратора ViewScript.Он отлично работает с декораторами FormElements.

ОБНОВЛЕНИЕ 2: Просто чтобы прояснить, я не возражаю против этого изменения имени, но это заставляет мои поля не заполняться, когда я вызываю form->заполнить.

Редактировать: Я думаю, что я сузил проблему до этого: когда я возвращаю свои значения обратно в setDefaults, они упорядочены следующим образом:

array(
\"formElements1-name\" => value1... \"subFormName\" => array(
\"parentFormName\" => array(
\"subFormName\" => subForm-values-array
)
)

... Основная проблема здесь "parentFormName" => "subFormNAme".., что она повторяется?Я уже в основной форме.Я предполагаю, что это вызвано тем, что я установил setElementsBelongTo(formName[subFormName]), но если бы я не сделал этого, то я бы получил значения своей подчиненной формы полностью отдельно от формы,

, то есть values ​​array = array(\ "formName \" => array (formValues), \ "subFormNAme \" => array (subFormValues)

, хотя я ожидаю, что это будет

array(
formName => array(
subFormNAme => values-array
)
)...

Возможно ли это вообщесделать эту работу?

Ответы [ 4 ]

8 голосов
/ 29 сентября 2011

Вы просто пытаетесь вывести свою форму, используя <?php echo $this->form; ?> из скрипта вида?

Это хорошо работает для простых форм, но для моих более сложных форм я склонен отображать каждый элемент отдельно, но неДля этого нужно использовать декоратор ViewScript для каждого отдельного элемента.Просто попробуйте что-то вроде этого в вашем скрипте вида:

<div class="form">
    <fieldset>
        <legend>Some Form Name</legend>
        <form action="<?php echo $this->escape($this->form->getAction()) ?>"
              method="<?php echo $this->escape($this->form->getMethod()) ?>"
              enctype="multipart/form-data">

            <?php echo $this->form->id; // render the id element here ?>

            <div class="half">
                <?php echo $this->form->name; // render the user name field here ?>
            </div>
            <div class="half">
                <?php echo $this->form->description; // render the description element here ?>
            </div>
            <div class="clear"></div>

            <div class="half">
                <?php echo $this->form->address1; // render the address ?>
            </div>
            <div class="half">
                <?php echo $this->form->address2; // render address2 ?>
            </div>
            <div class="clear"></div>

            <div class="third">
                <?php echo $this->form->zip; // render zip code ?>
            </div>
            <div class="third">
                <?php echo $this->form->city; // render city ?>
            </div>
            <div class="third">
                <?php echo $this->form->state; // render state ?>
            </div>
            <div class="clear"></div>

            <div class="half">
                <?php echo $this->form->country; // render country ?>
            </div>
            <div class="clear"></div>

            <?php echo $this->form->submit; ?>

        </form>
    </fieldset>
</div>

Именно так я делаю большинство моих форм, потому что я хочу, чтобы некоторые элементы занимали половину ширины, а другие - полную ширину.

Удивительно, но справочное руководство не говорит вам, что вы можете сделать это.Кажется, я помню страницу об этом в прошлом, но не могу найти ее сейчас.Когда я начал работать с Zend Framework, я думал, что единственный способ заставить мою форму выводить точно так, как я хотел, - это создавать сложные декораторы, но это не так.

Мэтью Вейер О'Пинни имеетотличный пост в блоге о рендеринге декораторов Zend_Form индивидуально , который объясняет, что я делал выше.Я надеюсь, что они добавят это на первую страницу Zend Form, потому что это поначалу меня обескураживало.Дело в том, что 90% моих форм визуализируют элементы по отдельности, а не просто отображают саму форму.

Примечание. Чтобы запретить ZF заключать элементы моей формы в теги dt и dd, я применяю этот декоратор квсе мои стандартные элементы формы.У меня есть базовый класс форм, из которого я расширяю все свои формы, поэтому мне не нужно повторять это везде.Это декоратор для элемента, поэтому я могу использовать теги для включения своих элементов.

public $elementDecorators = array(
    'ViewHelper',
    'Errors',
    array('Description', array('tag' => 'p',    'class' => 'description')),
    array('HtmlTag',     array('tag' => 'div', 'class' => 'form-div')),
    array('Label',       array('class' => 'form-label', 'requiredSuffix' => '*'))
);

Для кнопок отправки я использую

public $buttonDecorators = array(
    'ViewHelper',
    array('HtmlTag', array('tag' => 'div', 'class' => 'form-button'))
);
2 голосов
/ 04 октября 2011

Текущее решение - использовать декоратор PrepareElements для подчиненных форм с одним изменением - удалить рекурсивный вызов в коде PrepareElements.Кроме того, "setElementsBelongTo" не требуется.

Это похоже на правильные имена и идентификаторы.

0 голосов
/ 19 мая 2014

У меня была такая же проблема, и я решил ее с помощью декоратора

1: создание общей подчиненной формы с элементами

2: Использование специального декоратора с PrepareElements

3: изменить форму на массив с помощью setIsArray (true)

Пример:

Форма

$i = 4;
for($i = 0; $i < $nbReclam ; $i++)
{
    $rowForm = new Zend_Form_SubForm($i);
    $name= new Zend_Form_Element_Textarea('name');
    $rowForm->addElement($name);
    $this->addSubForm($rowForm, $i);
}

$this->setDecorators(array(
            'PrepareElements',
            array('ViewScript', array('viewScript' => 'myDecorator.phtml')),
    ));   


$this->setIsArray(true);

декоратор

<table>
<thead>
    <tr>
        <th>N°</th>
        <th>Name</th>
    </tr>
</thead>
<tbody>
    <?php foreach ($this->element->getSubForms() as $subForm) : ?>
            <tr>
               <td> <?php echo $i++?> </td>
               <?php foreach ($subForm->getElements() as $row) : ?>
                   <td><?php echo $row ?></td>
               <?php endforeach ?>
            </tr>
        <?php endforeach ?>
    </tbody>
</table>

Наслаждайтесь

Извините за мой английский, я француз

0 голосов
/ 12 июля 2012

Решением будет использование свойства элемента формы belongsTo().
Пример:

new Zend_Form_Element_Text('<elementName>', array('belongsTo' => '<subformName>'))

Таким образом, метод render () будет использовать имя элемента формы, например

name="<subformName>[<elementName>]"
...