Symfony:如何避免自定义表单类型自动包装到div中?

Symfony:如何避免自定义表单类型自动包装到div中?,symfony,twig,symfony-forms,symfony-2.4,Symfony,Twig,Symfony Forms,Symfony 2.4,用户类型表单: class UserType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('email', 'email', ['label' => 'EMail']); // various other fields.... } public function setDefault

用户类型表单:

class UserType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('email', 'email', ['label' => 'EMail']);
        // various other fields....
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'validation_groups' => array('registration'),
            'data_class' => 'Vendor\Model\Entity\User',
        ));
    }

    public function getName()
    {
        return 'form_user';
    }
}
class TutorType extends Translate
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('user', new UserType(), ['label' => false]);

        $builder->add('school', 'entity', [
            'class' => 'Model:School',
            'property' => 'name',
            'label' => 'Label'
        ]);

        // Various other fields
        $builder->add('save', 'Submit');
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            //'validation_groups' => array('registration'),
            'data_class' => 'Vendor\Model\Entity\Tutor',
            'cascade_validation' => true,
        ));
    }

    public function getName()
    {
        return 'form_tutor';
    }
}
TutorType表格:

class UserType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('email', 'email', ['label' => 'EMail']);
        // various other fields....
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'validation_groups' => array('registration'),
            'data_class' => 'Vendor\Model\Entity\User',
        ));
    }

    public function getName()
    {
        return 'form_user';
    }
}
class TutorType extends Translate
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('user', new UserType(), ['label' => false]);

        $builder->add('school', 'entity', [
            'class' => 'Model:School',
            'property' => 'name',
            'label' => 'Label'
        ]);

        // Various other fields
        $builder->add('save', 'Submit');
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            //'validation_groups' => array('registration'),
            'data_class' => 'Vendor\Model\Entity\Tutor',
            'cascade_validation' => true,
        ));
    }

    public function getName()
    {
        return 'form_tutor';
    }
}
渲染时,
UserType
是在div中渲染的,我找不到解决这个问题的方法

该表单呈现为

<form name="form_tutor"
      method="post"
      action=""
      novalidate="novalidate"
      class="form-horizontal form-horizontal"
      id="form_tutor">
    <div id="form_tutor"
         novalidate="novalidate"
         class="form-horizontal">
        <div class="form-group">
            <div class="col-lg-10">
                <div id="form_tutor_user">
                    <div class="form-group">
                        <label class="col-lg-2 control-label aaaa required"
                             for="form_tutor_user_email">EMail</label>

                        <div class="col-lg-10">
                            <input type="email"
                                 id="form_tutor_user_email"
                                 name="form_tutor[user][email]"
                                 required="required"
                                 class="form-control" />
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <div class="form-group">
            <label class="col-lg-2 control-label aaaa required"
                 for="form_tutor_tutorType">Type</label>

            <div class="col-lg-10">
                <select id="form_tutor_tutorType"
                     name="form_tutor[tutorType]"
                     class="form-control">
                    </select>
            </div>
        </div>

        <div class="form-group">
            <div class="col-lg-offset-2 col-lg-10">
                <button type="submit"
                     id="form_tutor_save"
                     name="form_tutor[save]"
                     class="btn btn-default">Speichern</button>
            </div>
        </div><input type="hidden"
             id="form_tutor__token"
             name="form_tutor[_token]"
             class="form-control"
             value="s6i6zPxJs7KU5CiEe8i6Ahg_ca8rc2t5CnSk5yAsUhk" />
    </div>
</form>


电子邮件
类型
斯皮切恩
form\u tutor\u用户
包装在自己的表单组div中。 我试图覆盖form\u tutor\u user\u小部件,但这只是一个层次。(而且只是一个快速修复,它应该全局应用于所有表单类型类)

如何更改主题,使所有自定义类型不使用默认的form_行模板包装

或者,我如何知道在细枝中何时呈现“子窗体”? 因此,当子节点不是子表单时,我可以决定打印
,如果是这种情况,则可以跳过它


TIA

理论上,如果您以这种方式覆盖全局表单主题中的
表单小部件复合块
块,它应该可以正常工作:

// app/Resources/views/form.html.twig

{% block form_widget_compound %}
    {% if form.parent is empty %}
        <div {{ block('widget_container_attributes') }}>
        {{ form_errors(form) }}
    {% endif %}
    {{ block('form_rows') }}
    {{ form_rest(form) }}
    {% if form.parent is empty %}
        </div>
    {% endif %}
{% endblock %}

我通常通过手动呈现嵌套表单的字段来解决此问题:

{{ form_row(form.tutor.school) }}
{{ form_row(form.tutor.user.email) }}

可能这不是最优雅的解决方案,但它对我很有效,我还没有找到一个优雅的解决方案。

默认情况下,在基本表单主题中:

// app/config/config.yml
twig:
    form:
        resources:
            - "::form.html.twig"
{% block form_row %}
{% spaceless %}
    <div>
        {{ form_label(form) }}
        {{ form_errors(form) }}
        {{ form_widget(form) }}
    </div>
{% endspaceless %}
{% endblock form_row %}
{% form_theme form with ['BundleName:ControlerName:somesubform_form.html.twig'] %}
。。。和继承的形式:

class MyFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        ...
    }

    public function getName()
    {
        return 'my_form';
    }

    public function getParent()
    {
        return 'top_form';
    }
}
如您所见,表单主题化继承不需要进行PHP继承

模板主题化方面(我甚至可以这么说吗?),如果没有为我的表单设置特定的表单主题,Symfony会理解这里使用的默认表单主题是顶部表单的表单主题,您可以这样定义:

{% block top_form_widget %}
{% spaceless %}
    {% for child in form %}
        <div class="form-group">
            {{ form_widget(child) }}
        </div>
    {% endfor %}
    {{ form_rest(form) }}
{% endspaceless %}
{% endblock top_form_widget %}
{%block top\u form\u widget%}
{%spaceless%}
{表格%中的子项为%1}
{{form_widget(child)}
{%endfor%}
{{form_rest(form)}
{%endspaceless%}
{%endblock top_form_widget%}
我应该补充一点,这是我已经遇到并解决的问题。告诉我这对你有什么作用

编辑:

总而言之,你要做的是:

  • 创建TopType表单类型
  • 在表单主题中添加顶部表单小部件
  • 对于所有根窗体(即顶级窗体,没有父窗体的窗体),添加一个getParent()方法,该方法将返回TopType窗体的名称(“top_窗体”)
尝试使用表单主题

首先,在父模板中定义表单主题:

// app/config/config.yml
twig:
    form:
        resources:
            - "::form.html.twig"
{% block form_row %}
{% spaceless %}
    <div>
        {{ form_label(form) }}
        {{ form_errors(form) }}
        {{ form_widget(form) }}
    </div>
{% endspaceless %}
{% endblock form_row %}
{% form_theme form with ['BundleName:ControlerName:somesubform_form.html.twig'] %}
顺便说一下,用专有名称替换BundleName、ControllerName和somesubform

然后使用以下命令渲染它:

{{ form_row(form.somesubform) }}

也许这不是一个优雅的解决方案,但是对我来说很有效,因为我也在努力寻找解决方案

例如:

{% for custom_field in form.custom_fields %}
<div class="edit_custom">
{{ form_row(custom_field.name) }}
{{ form_row(custom_field.value) }}
</div>
{% endfor %}

<script>
$('.edit_custom').find('input').unwrap();
</script>
{%用于表单中的自定义\u字段。自定义\u字段%}
{{form_row(custom_field.name)}
{{form_row(custom_field.value)}
{%endfor%}
$('.edit_custom')。查找('input')。展开();

Bootstrap 3.3.4我最终做到了这一点

它们是其中的关键部分:

 <div class="{% if form.parent.parent is empty %}form-group{% endif %}{% if (not compound or force_error|default(false)) and not valid %} has-error{% endif %}">

完整模板。

{% block form_row -%}
    <div class="{% if form.parent.parent is empty %}form-group{% endif %}{% if (not compound or force_error|default(false)) and not valid %} has-error{% endif %}">
        {% if form.parent.parent is null and label is not empty %}
            {{- form_label(form) -}}
        {% elseif label is empty %}
            {{- form_label(form) -}}
        {% endif %}
        {% if compound is empty %}<div class="{{ block('form_group_class') }}">{% endif %}
            {{- form_widget(form) -}}
            {{- form_errors(form) -}}
        {% if compound is empty %}</div>{% endif %}
    </div>
{%- endblock form_row %}
{%block form_row-%}
{%如果form.parent.parent为空且标签不为空%}
{{-form_标签(form)-}
{%elseif标签为空%}
{{-form_标签(form)-}
{%endif%}
{%if化合物为空%}{%endif%}
{{-form_小部件(form)-}
{{-form_错误(form)-}
{%if化合物为空%}{%endif%}
{%-endblock form_row%}

首先,感谢您的回答,不幸的是,这不起作用。这个化合物也是嵌套的。(复合码中的复合码)谢谢你的回答。这是我目前的解决方法,但我正在需要许多表单,这将改变很多(agil项目),每次我改变表单时改变视图不是我想要的。如果你找到更好的方法,我很高兴知道。这从来都不是我的首要任务。这个解决方案简单、有效,即使几个月后我回到代码中,也很容易理解——完美!您在那里使用的引导包是什么?或者这是你自己定制的boostrap表单主题?标准版没有使用和呈现带有
表单组的div(但是主题文件稍微修改以匹配我的html),我会尝试一下,但似乎我最终会在主题文件中包含很多表单小部件块。这么长时间是最好的解决方案。谢谢,伙计。但是我只计算了一个表单主题块和一个类作为整个解决方案?我文章中的前两个主题块来自SF2默认表单主题,它们只是为了解释。也许我理解错了,但是我的表单和顶部表单必须是唯一的字符串,不是吗?我在这个应用程序中有超过20个表单/子表单。在SF2中,您必须按表单类型有一个单独的表单名称(“top_form”、“my_form”,即getName()返回的字符串),每个表单类型都不同。为更清晰的方向进行后期编辑。是的,这就是我的意思。。但无论如何,这仍然是迄今为止最好的解决方案。谢谢西风!与此同时,我也得出了同样的解决方案——但忘了评论它。谢谢你的回答。