Twig - Iterating over Form fields

时间:2017-12-18 07:48:30

标签: php forms symfony twig

I'm facing a problem trying to iterate over all form elements in a Twig form theme. Actually I used this to iterate over them:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <input type="checkbox" id="chk1" value="1" class="chk" onclick="CheckBox(this)" />1
  <input type="checkbox" id="chk2" value="2" class="chk" onclick="CheckBox(this)" />2
  <input type="checkbox" id="chk3" value="3" class="chk" onclick="CheckBox(this)" />3
  <input type="checkbox" id="chk4" value="4" class="chk" onclick="CheckBox(this)" />4
  <input type="button" id="btn" value="alert" />
</div>

I didn't found it in documentation, I just dumped form variable and found the fields on that path. This actually works well with all forms except when the form itself has a parameter called children. I don't know if it's a bug because if you just dump {% for child in form.parent.children %} object the structure is the same in both cases:

enter image description here

But if you try to access form when it has a form.parent.children parameter inside you won't get that array rather directly the result of children:

enter image description here

As you can see in this case "children" refers directly to form's children element (same identifier #1592). Still if you try to get form.parent.children you will get again form.parent.children.parent.children element so basically using this way is not possible to iterate over form fields if form contains a parameter called children.

Is it a bug or am I missing something? Maybe there's another way to achieve what I want?

1 个答案:

答案 0 :(得分:2)

是的,这是与the way Twig accesses each attribute for convenience相关的名称冲突,因为FormView被声明为\ArrayAccess it has priority over object's properties。顺便说一下,parentvars属性会发生同样的情况,但现在让我们关注解决方案,而不是问题。

由于这是一个Twig的问题,解决方案应该针对这个方向。解决方法可能是create a custom function,可以正确获取FormView的属性:

public function getFunctions()
{
    return array(
        new TwigFunction('formview_prop', array($this, 'getFormViewProperty')),
    );
}

public function getFormViewProperty(FormView $formView, string $prop)
{
    // parent, children or vars
    return $formView->{$prop};
}

因此,使用此功能时,您可以访问视图的属性而不是表单的字段(如果存在名称冲突):

{% for child in formview_prop(form, 'parent') %}

然后,它将迭代父视图的所有字段元素(子元素)。但是,我希望通过创建三个函数formview_parentformview_childrenformview_vars来明确,而不是传递第二个参数。

从这个意义上讲,您可能还需要验证表单是否具有父视图,因此自Symfony 2.7.39, 2.8.32, 3.3.14, 3.4.1, 4.0.1 was introduced(作为错误修复)新的Twig的测试函数名为rootform以避免这种碰撞,特别是parent属性:

{% if form is rootform %}