在嵌套子表单上使用 ViewScript 装饰器 (Zend Form)

发布于 2024-12-06 18:57:58 字数 1645 浏览 4 评论 0原文

我想使用视图脚本来渲染我的 zend 表单,因为这似乎是最好的方法 控制表单的布局/设计,同时仍然使用 Zend_Elements 类。

在视图脚本中,我使用 $this->element->getElement('elementName') 渲染元素。

我在元素名称方面遇到问题。这实际上是表单内子表单内的子表单。

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

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

有什么想法我应该如何处理这个问题吗?

谢谢。

更新:我尝试调试PrepareElements,但我真的不明白在做什么。 看起来它在第一次迭代中工作正常,但是当在其中一个中间子表单上运行时,它再次添​​加 form[subform] 前缀。

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

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

我尝试更改belongsTo,但只替换了“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]) ,但如果我不这样做,那么我会得到与表单完全分离的子表单值,

IE 值数组=数组( \"表单名称\" =>大批( 表单值 ), \"subFormNAme\" =>;大批( 子表单值 )

,而我希望它

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

是 甚至有可能使这项工作成功吗?

I want to use a view script to render my zend form as it seems to be the best way to
control the layout/design of the form while still using the Zend_Elements classes.

From the view script, I render the element with $this->element->getElement('elementName') .

I'm having problems with the names of the elements. This is actually a sub-form inside a sub-form inside a form.

When I used the FormElements decorators , the fully qualified name of the elements was form[subForm][subForm][element] , which was good.
Wehn I moved to the viewScript decorators, it changed to subForm[subForm][element].

I understood that I need to use the PrepareElements decorator to fix this, but this caused the name to change form[subForm][form][subForm][subForm][elements] (it doubled the first two names in the start).

Any ideas how I should handle this?

Thanks.

UPDATE: I tried to debug PrepareElements and I really don't understand what is doing.
It seems like it works ok in the first iteration, but then it adds again the form[subform] prefix when running on one of the middle subforms.

When I'm not using the PrepareElements decorator, I'm just missing the "form" prefix in the names (i.e., instead of form[subForm][element], I get only subForm[element]).

May be I can just fix this somehow?

I tried to change the belongsTo but that only replaced the "subForm" prefix .

It actually seems like what is missing is a belongsTo method on the subForm.

Again, this is all because of the ViewScript decorator. It works fine with the FormElements decorators.

UPDATE 2: Just to clarify, I wouldn't mind this name change, but it causes my fields to not populate when I call form->populate .

Edit: I think that I've narrowed the problem to this: when I get my values back in setDefaults, they are ordered like this:

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

...
The main problem here is the "parentFormName" => "subFormNAme".. what does it repeat itself? I'm already in the main form. I'm guessing this is caused because I've set the setElementsBelongTo(formName[subFormName]) , but if I wouldn't do that, then I would get my subform values completely separate from the form,

i.e.
values array = array(
\"formName\" => array(
formValues
), \"subFormNAme\" => array(
subFormValues
)

, while I exepct it to be

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

Is it even possible to make this work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

零時差 2024-12-13 18:57:58

您是否只是想使用 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'))
);

Are you just trying to output your form using <?php echo $this->form; ?> from your view script?

That works well for simple forms, but for my more complex forms I tend to render each element individually but don't need to use ViewScript decorator on each individual element to do this. Just try something like this from your view script:

<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>

That is how I do most of my forms because I want to have some elements take up half the width and others the full width.

Surprisingly, the reference guide doesn't tell you that you can do this. I seem to remember a page about it in the past but cannot find it now. When I got started with Zend Framework, I thought the only way I could get my form to output exactly how I wanted was to create complex decorators, but that is not the case.

Matthew Weier O'Phinney has a great blog post on rendering Zend_Form decorators individually which explains what I did above. I hope they add this to the first page of Zend Form because that was discouraging to me at first. The fact is, 90% of my forms render elements individually instead of just echo'ing the form itself.

Note: To stop ZF from enclosing my form elements in the dt and dd tags, I apply this decorator to all of my standard form elements. I have a base form class that I extend all of my forms from so I don't have to repeat this everywhere. This is the decorator for the element so I can use tags to enclose my elements.

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' => '*'))
);

For my submit buttons I use

public $buttonDecorators = array(
    'ViewHelper',
    array('HtmlTag', array('tag' => 'div', 'class' => 'form-button'))
);
心凉怎暖 2024-12-13 18:57:58

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

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

The current solution is to use the PrepareElements decorator on the subforms with one change - remove the recursive call in the PrepareElements code. Also, no "setElementsBelongTo" is required.

This seem to generate the correct names and ids.

话少情深 2024-12-13 18:57:58

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

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

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

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

The solution would be to use the belongsTo() form element property.
Example :

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

In this way, the render() method will use a form element name like

name="<subformName>[<elementName>]"
撩人痒 2024-12-13 18:57:58

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

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>

享受

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

I had the same problem and i solved it with a decorator

1 : Create a generic subform with elements

2 : Using a specific decorator with PrepareElements

3 : Change form to an array with setIsArray(true)

Example :

Form

$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);

Decorator

<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>

Enjoy

Sorry for my english, i am french

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文