避免Symfony强制显示表单字段

rseugnpd  于 2023-10-24  发布在  其他
关注(0)|答案(5)|浏览(103)

我有一个表单类型,设置了10个字段。在我的twig模板中,我每次显示8个字段,每个条件中有2个字段:

{% if computed is not empty %}
    <div class="container-filters">
        <div class="form-group">
             {{ form_row(form.filterStart) }}
        </div>
        <div class="form-group">
              {{ form_row(form.filterEnd) }}
        </div>
        <input type="submit" name="submit" class="btn btn-evo" value="OK" />
    </div>
{% endif %}

但是不管我的条件是true还是false,Symfony都会显示这两个字段。如果我的条件是true,它们会因为我的{{ form_row()}}语句而显示,这是正常的行为。如果我的条件是false,它们无论如何都会显示,因为Symfony 2强制显示表单字段。
我该如何避免这种奇怪的行为?

fwzugrvs

fwzugrvs1#

我猜你有一个form_end或form_rest在你呈现的代码之后的某个地方。
您可以告诉不要在form_end helper中呈现剩余的字段:

{# don't render unrendered fields #}
{{ form_end(form, {'render_rest': false}) }}

http://symfony.com/doc/current/reference/forms/twig_reference.html
顺便说一句,我建议在FormType中添加逻辑。

vohkndzv

vohkndzv2#

您可以强制项目已被渲染像..

{% do form.filterStart.setRendered %}
{% do form.filterEnd.setRendered %}

如果您使用的是{{ form_end(form, {'render_rest': false}) }},那么您应该知道您需要呈现您的CSRF令牌,除非您特别将其关闭。
这两种方法都可能会清除模型上的值,因为它们不在发布的数据中。
或者,你可以把字段放在一个隐藏的div中,但这有点古怪(其他方法也是如此)。
正如Christophe所提到的,最好的方法是将其添加到表单逻辑中。您选择的方法取决于这些字段的可用性是否取决于预定的因素或来自实际模型的数据。

预定

您的表单类型

class YourFormType extends AbstractType
{
    //...

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        //...

        if ($options['your_condition']) {
            $builder
                ->add('filterStart', 'date')
                ->add('filterEnd', 'date')
            ;
        }
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            //...
            'your_condition' => false,
        ));
    }

    //...
}

创建您的表单

$form = $formFactory->create(
        // Or $this->createForm if you are using the controller
    'your_form_name', 
    $model, 
    array('your_condition' => true/false)
);

模型

表单类型

class YourFormType extends AbstractType
{
    //...

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        //...

        $builder
            ->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event) {
                $form = $event->getForm();
                $model = $event->getData();

                if (!$model || 'something' !== $model->getSomething()) {
                    return;
                }

                $form
                    ->add('filterStart', 'date')
                    ->add('filterEnd', 'date')
                ;
            })
        ;
    }

    //...
}

这些麻烦将要求您检查字段已创建时,在您的模板中渲染它们一样。

{% if form.filterStart is defined and form.filterEnd is defiend %}
    <div class="container-filters">
        <div class="form-group">
            {{ form_row(form.filterStart) }}
        </div>
        <div class="form-group">
            {{ form_row(form.filterEnd) }}
        </div>
        <input type="submit" name="submit" class="btn btn-evo" value="OK" />
    </div>
{% endif %}
h9a6wy2h

h9a6wy2h3#

由于FormView->children具有公共访问权限,因此您可以将逻辑处理到控制器中:

if(<condition>) {
    $formView->children['filterStart']->setRendered();
    $formView->children['filterEnd']->setRendered();
}
1wnzp6jl

1wnzp6jl4#

如果你有一个表单,你想在两个模板上以不同的方式显示,你可以直接在你的控制器中删除一个特定的字段:

public function firstWayAction()
{
    $form = $this->createForm(new RemoveFormFieldType());

    $form->remove('second');

    // form processing...   
    return $this->render('QADayBundle:RemoveFormField:form.html.twig', array(
        'form' => $form->createView()
    ));
}

请参阅此文章了解更多详细信息:https://symfonycasts.com/screencast/question-answer-day/remove-form-field

oxcyiej7

oxcyiej75#

你可以在你的twig中设置“style=display:none”。

<div style= "display:none">
    {{ form_row(form.filterStart) }}
</div>

相关问题