Symfony twig如何将类添加到表单行

lop*_*ded 17 symfony-forms symfony twig

我正在使用Twig在Symfony 2.3中构建一个项目.我想在表格行块中添加一个类.我使用的表单主题文件包含:

{% block form_row %}
    <div class="form-row">
        {{ form_label(form) }}
        {{ form_widget(form) }}
        {{ form_errors(form) }}
    </div>
{% endblock %}
Run Code Online (Sandbox Code Playgroud)

现在我的一些表单行要添加一个额外的类form-row-split.我无法弄清楚如何正确地做到这一点.我几乎工作的方式是:

{% block form_row %}
    {% set attr = attr|merge({'class': 'form-row' ~ (attr.class is defined ? ' ' ~ attr.class : '') ~ (errors|length > 0 ? ' error' : '')} ) %}
    <div {{ block('widget_container_attributes') }}>
        {{ form_label(form) }}
        {{ form_widget(form) }}
        {{ form_errors(form) }}
    </div>
{% endblock %}
Run Code Online (Sandbox Code Playgroud)

(注意,我已经将error类逻辑留在那里,因为它需要保留).然后在表单构建器中:

$builder
        ->add('first_name', 'text', array(
            'attr' => array(
                'class' => 'form-row-split'
            )
        ));
Run Code Online (Sandbox Code Playgroud)

这几乎可以工作,但它在任何地方都添加了这个类,并且还将行ID添加到行中!

<div id="myform_first_name" class="form-row form-row-split">
    <label for="myform_first_name">First name</label>
    <input id="myform_first_name" class="form-row-split" type="text" name="myform[first_name]">
</div>
Run Code Online (Sandbox Code Playgroud)

我可以想到一些可能的解决方案,但没有一个是美观或直接的.当然必须有一个简单的方法来做到这一点?

lop*_*ded 23

实际上有一个相当简单的解决方案.我只需要一个表单类型扩展来扩展基本表单类型以允许额外的可用选项:http://symfony.com/doc/2.3/cookbook/form/create_form_type_extension.html

通过文档中的示例,我创建了一个新的表单类型扩展:

// src/Acme/FrontendBundle/Form/Extension/FormTypeExtension.php

namespace Acme\FrontendBundle\Form\Extension;

use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

/**
 * Class FormTypeExtension
 * @package Acme\FrontendBundle\Form\Extension
 */
class FormTypeExtension extends AbstractTypeExtension
{
    /**
     * Extends the form type which all other types extend
     *
     * @return string The name of the type being extended
     */
    public function getExtendedType()
    {
        return 'form';
    }

    /**
     * Add the extra row_attr option
     *
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'row_attr' => array()
        ));
    }

    /**
     * Pass the set row_attr options to the view
     *
     * @param FormView $view
     * @param FormInterface $form
     * @param array $options
     */
    public function buildView(FormView $view, FormInterface $form, array $options)
    {
        $view->vars['row_attr'] = $options['row_attr'];
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我在我的捆绑包中注册了该服务......

<!-- Form row attributes form extension -->
<service id="acme.form_type_extension" class="Acme\FrontendBundle\Form\Extension\FormTypeExtension">
    <tag name="form.type_extension" alias="form" />
</service>
Run Code Online (Sandbox Code Playgroud)

由于每个小部件都扩展了基本表单类型,因此允许我row_attr在任何字段上传递此新选项,例如:

$builder
    ->add('first_name', 'text', array(
        'row_attr' => array(
            'class' => 'form-row-split'
        )
    ));
Run Code Online (Sandbox Code Playgroud)

然后树枝覆盖以使用新row_attr选项:

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

{% block form_row_attributes %}
    {% spaceless %}
        {% for attrname, attrvalue in row_attr %}{{ attrname }}="{{ attrvalue }}" {% endfor %}
    {% endspaceless %}
{% endblock form_row_attributes %}
Run Code Online (Sandbox Code Playgroud)

它已经完成了!

(为了完整性,我的完整twig覆盖仍然合并在form-rowerror类中,如下所示:

{% set row_attr = row_attr|merge({'class': 'form-row' ~ (row_attr.class is defined ? ' ' ~ row_attr.class : '') ~ (errors|length > 0 ? ' error' : '')} ) %}
Run Code Online (Sandbox Code Playgroud)

..但这不是回答我自己的问题所必需的:P)


pom*_*axa 16

文档说:你总是能够将attr传递给渲染元素:

{{ form_start(form, {'attr': {'class': 'your-class'}} ) }}
    {{ form_label(form, {'attr': {'class': 'your-class'}}) }}
    {{ form_widget(form, {'attr': {'class': 'your-class'}}) }}
    {{ form_errors(form, {'attr': {'class': 'your-class'}}) }}
{{ form_end(form) }}
Run Code Online (Sandbox Code Playgroud)

  • 这只允许你将`attr`传递给表单,标签,小部件,错误,而不是行.事实上,如果你看一下原始的主题文件(`form_div_layout.html.twig`)你可以看到在`form_row`块中,周围的`<div>`将永远不会注入任何传递的变量...因此我的问题这该怎么做.谢谢你的建议. (6认同)

Pav*_*nin 5

下面是@lopsided的答案的克隆,但更改反映了最新的Symfony结构更改(v.2.7 +):


实际上有一个相当简单的解决方案.我只需要一个表单类型扩展来扩展基本表单类型以允许额外的可用选项:http://symfony.com/doc/master/form/create_form_type_extension.html

通过文档中的示例,我创建了一个新的表单类型扩展:

// src/Acme/FrontendBundle/Form/Extension/FormTypeExtension.php

namespace Acme\FrontendBundle\Form\Extension;

use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
 * Class FormTypeExtension
 * @package Acme\FrontendBundle\Form\Extension
 */
class FormTypeExtension extends AbstractTypeExtension
{
    /**
     * Extends the form type which all other types extend
     *
     * @return string The name of the type being extended
     */
    public function getExtendedType()
    {
        return FormType::class;
    }

    /**
     * Add the extra row_attr option
     *
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'row_attr' => []
        ));
    }

    /**
     * Pass the set row_attr options to the view
     *
     * @param FormView $view
     * @param FormInterface $form
     * @param array $options
     */
    public function buildView(FormView $view, FormInterface $form, array $options)
    {
        $view->vars['row_attr'] = $options['row_attr'];
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我在我的捆绑包中注册了该服务......

<!-- Form row attributes form extension -->
<service id="acme.form_type_extension" class="Acme\FrontendBundle\Form\Extension\FormTypeExtension">
    <tag name="form.type_extension" alias="form" extended_type="Symfony\Component\Form\Extension\Core\Type\FormType" />
</service>
Run Code Online (Sandbox Code Playgroud)

由于每个小部件都扩展了基本表单类型,因此允许我row_attr在任何字段上传递此新选项,例如:

$builder
    ->add('first_name', TextType:class, [
        'row_attr' => [
            'class' => 'form-row-split'
        ]
    ]);
Run Code Online (Sandbox Code Playgroud)

然后树枝覆盖以使用新row_attr选项:

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

{% block form_row_attributes %}
    {% spaceless %}
        {% for attrname, attrvalue in row_attr %}{{ attrname }}="{{ attrvalue }}" {% endfor %}
    {% endspaceless %}
{% endblock form_row_attributes %}
Run Code Online (Sandbox Code Playgroud)

它已经完成了!

(为了完整性,我的完整twig覆盖仍然合并在form-rowerror类中,如下所示:

{% set row_attr = row_attr|merge({'class': 'form-row' ~ (row_attr.class is defined ? ' ' ~ row_attr.class : '') ~ (errors|length > 0 ? ' error' : '')} ) %}
Run Code Online (Sandbox Code Playgroud)

..但这不是回答我自己的问题所必需的:P)