首页 > 解决方案 > Form builder and theming variables in symfony 4

问题描述

There are situations where my form inputs would have icons, and some without. Originally, I thought I would be able to put the class within the form builder like so:

$builder
        ->add('email', EmailType::class, [
            'label' => 'Email address',
            'attr' => [
                'placeholder' => 'john.smith@foo.com',
                'class' => 'has_icon icon_email'
            ],
            'constraints' => [
                new NotBlank([
                    'message' => 'Enter an email address.'
                ])
            ]
        ])

And then the output within the form template could potentially take the class and reconfigure the appearance. Clearly this isn't working, but this was the direction I was going in:

{% block form_row %}
    <div class="form_row">
        {{ form_label(form) }}
        {% if form.vars.attr.class == 'has_icon' %}
            test
        {% endif %}
        {{ form_errors(form) }}
    </div>
{% endblock form_row %}

Is this the right approach or is there another more dependable way of going about this?


Edit 9/22/2019

I wanted to do a test and it was interesting because if I were to try to access the form's block prefixes, I can by specifying in the form theme like so:

block_prefixes.2 == "password" and this will access that array within block prefixes and check for that. However, if I were to access attr then the class option like so:

attr.class it will return an error Key "class" does not exist as the array is empty. Why is that? How can I readily access the array within attr?

标签: twigsymfony4

解决方案


我认为您想为每个输入创建一个自定义 FormType 然后在您的主题中为每个输入使用自定义 fom_widget 就像在内置Symfony\Component\Form\Extension\Core\Type\PercentTypebootstrap_4_layout.html.twig

表格类型:

// src:"/vendor/symfony/form/Extension/Core/Type/PercentType.php"

namespace Symfony\Component\Form\Extension\Core\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\DataTransformer\PercentToLocalizedStringTransformer;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;

class PercentType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->addViewTransformer(new PercentToLocalizedStringTransformer($options['scale'], $options['type']));
    }

    /**
     * {@inheritdoc}
     */
    public function buildView(FormView $view, FormInterface $form, array $options)
    {
        $view->vars['symbol'] = $options['symbol'];
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'scale' => 0,
            'symbol' => '%',
            'type' => 'fractional',
            'compound' => false,
        ]);

        $resolver->setAllowedValues('type', [
            'fractional',
            'integer',
        ]);

        $resolver->setAllowedTypes('scale', 'int');
        $resolver->setAllowedTypes('symbol', ['bool', 'string']);
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'percent';
    }
}

形式主题:

// src:"/vendor/symfony/twig-bridge/Resources/views/Form/bootstrap_4_layout.html.twig"
...

{% block percent_widget -%}
    {%- if symbol -%}
        <div class="input-group">
            {{- block('form_widget_simple') -}}
            <div class="input-group-append">
                <span class="input-group-text">{{ symbol|default('%') }}</span>
            </div>
        </div>
    {%- else -%}
        {{- block('form_widget_simple') -}}
    {%- endif -%}
{%- endblock percent_widget %}

...

推荐阅读