6

我想使用视图脚本来呈现我的 zend 表单,因为它似乎是在仍然使用 Zend_Elements 类的同时控制表单布局/设计的最佳方式。

在视图脚本中,我使用$this->element->getElement('elementName').

我对元素的名称有疑问。这实际上是一个表单里面的一个子表单里面的一个子表单。

当我使用 FormElements 装饰器时,元素的完全限定名称是 form[subForm][subForm][element] ,这很好。Wehn 我移到 viewScript 装饰器,它更改为 subForm[subForm][element]。

我知道我需要使用 PrepareElements 装饰器来解决这个问题,但这导致名称更改 form[subForm][form][subForm][subForm][elements] (它在开始时将前两个名称翻了一番)。

任何想法我应该如何处理这个?

谢谢。

更新:我试图调试 PrepareElements,但我真的不明白在做什么。似乎它在第一次迭代中工作正常,但随后在其中一个中间子表单上运行时再次添加了 form[subform] 前缀。

当我不使用 PrepareElements 装饰器时,我只是缺少名称中的“form”前缀(即,我只得到 subForm[element],而不是 form[subForm][element])。

也许我可以以某种方式解决这个问题?

我试图改变belongsTo,但只替换了“subForm”前缀。

实际上,似乎缺少的是 subForm 上的 belongsTo 方法。

同样,这都是因为 ViewScript 装饰器。它适用于 FormElements 装饰器。

更新 2:澄清一下,我不介意这个名称更改,但是当我调用 form->populate 时,它​​会导致我的字段不填充。

编辑:我认为我已经将问题缩小到这个:当我在 setDefaults 中取回我的值时,它们的顺序如下:

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

...这里的主要问题是"parentFormName" => "subFormNAme"..它会重复什么?我已经是主要形式了。我猜这是因为我设置了setElementsBelongTo(formName[subFormName]),但如果我不这样做,那么我的子表单值将与表单完全分开,

即值数组=数组(\“formName\”=>数组(formValues),\“subFormNAme\”=>数组(subFormValues)

, 虽然我希望它是

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

甚至有可能完成这项工作吗?

4

4 回答 4

8

你只是想<?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 时,我认为让表单准确输出我想要的方式的唯一方法是创建复杂的装饰器,但事实并非如此。

Matthew Weier O'Phinney 有一篇很棒的博客文章,介绍了单独渲染 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'))
);
于 2011-09-28T22:12:28.703 回答
2

当前的解决方案是在子窗体上使用 PrepareElements 装饰器,只需进行一项更改 - 删除 PrepareElements 代码中的递归调用。此外,不需要“setElementsBelongTo”。

这似乎生成了正确的名称和 ID。

于 2011-10-04T13:15:08.207 回答
0

解决方案是使用belongsTo()表单元素属性。
例子 :

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

这样,render() 方法将使用一个表单元素名称,如

name="<subformName>[<elementName>]"
于 2012-07-12T13:33:24.327 回答
0

我有同样的问题,我用装饰器解决了它

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>

享受

对不起我的英语,我是法国人

于 2014-05-19T13:03:23.943 回答