9

用户类型表格:

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';
    }
}

渲染时,在UserTypediv 内渲染,我找不到解决此问题的方法。

表单呈现为

结果

<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_tutor_user包裹在自己的表单组 div 中。我试图覆盖 form_tutor_user_widget 但这是一个更深的层次。(而且只是一个快速修复,它应该全局应用于所有表单类型 - 类)

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

或者我怎么知道何时呈现“子表单”?所以我可以决定<div class="form-group">在子节点不是子表单时打印,或者在这种情况下跳过它。

TIA

4

6 回答 6

4

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

{% block form_row %}
{% spaceless %}
    <div>
        {{ form_label(form) }}
        {{ form_errors(form) }}
        {{ form_widget(form) }}
    </div>
{% endspaceless %}
{% endblock form_row %}

并且,对于自定义复合形式:

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

除非您在此处更改某些内容,否则您看到的 DIV 应该来自模板的一个或另一个位。

但是,在您的特定示例中,如果定义了form_tutor_user_row,则永远不会使用第一位,如果定义了form_tutor_user_widget,则永远不会使用最后一位。

回到你的问题。您的问题是: “我怎样才能更改主题,以便所有自定义类型都不用默认的 form_row 模板包装?”

这是我看到的问题:您希望您的 TOP 表单(包含所有子表单的表单)都有一个共同的呈现方式,分段。每个部分都将包含在 class="form-group" 的 DIV 中。您可能想要添加一些额外的渲染操作,但我会限制自己这样做以保持简单。

然后你需要做的是创建一个特定的表单类型并让你所有的 TOP 表单都继承自这个新的表单类型。例如:

class TopType extends AbstractType
{
    public function getName()
    {
        return 'top_form';
    }
}

...和继承的形式:

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

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

    public function getParent()
    {
        return 'top_form';
    }
}

如您所见,表单主题继承无需进行 PHP 继承即可工作。

模板主题(我可以这么说吗?),如果没有为my_form设置特定的表单主题,Symfony 将理解这里使用的默认表单主题是top_form的表单主题,您可以这样定义:

{% 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 %}

我应该补充一点,这是我已经遇到并解决的问题。告诉我这对你有什么作用。

编辑:

总结一下,你要做的是:

  • 创建 TopType 表单类型,
  • 在表单主题中添加top_form_widget块,
  • 对于您的所有根表单(即顶级表单、没有父级的表单),添加一个getParent()方法,该方法将返回您的 TopType 表单的名称(“top_form”)
于 2014-03-03T16:18:34.647 回答
3

理论上,如果您form_widget_compound以这种方式覆盖全局表单主题中的块,它应该可以按您的意愿工作:

// 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 %}

并注册您的表单主题:

// app/config/config.yml
twig:
    form:
        resources:
            - "::form.html.twig"
于 2014-02-27T23:43:20.933 回答
3

我通常通过手动渲染嵌套表单的字段来解决这个问题:

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

可能这不是最优雅的解决方案,但它适用于我,我还没有寻找一个优雅的解决方案。

于 2014-02-28T14:46:36.347 回答
1

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 %}
于 2019-10-23T18:41:17.733 回答
0

也许这不是一个优雅的解决方案,但对我有用,因为我也在试图找到解决方案。

举个例子:

{% 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>
于 2015-12-01T04:53:02.673 回答
-1

尝试使用 form_themes。

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

{% form_theme form with ['BundleName:ControlerName:somesubform_form.html.twig'] %}

顺便说一句,用正确的名称替换 BundleName、ControllerName 和 somesubform。

然后渲染它:

{{ form_row(form.somesubform) }}
于 2014-03-03T16:23:57.843 回答