简体   繁体   English

Symfony3动态表单复选框

[英]Symfony3 dynamic form checkbox

I have a form where I use a checkbox to filter an EntityType. 我有一个使用复选框过滤EntityType的表单。 When the form is first rendered, the checkbox is unchecked (false). 首次呈现表单时,未选中该复选框(false)。 When I check it, it correctly fires my AJAX, and my entity is updated with the correct subset. 当我检查它时,它会正确触发我的AJAX,并使用正确的子集更新我的实体。

However, when I then go to uncheck the checkbox, the new entities remain. 但是,当我然后取消选中该复选框时,将保留新实体。

While going through the code, I've verified that the AJAX request is sending the proper true/false back to my form (the POST parameters in the profiler are correct to what I've sent). 在检查代码时,我已验证AJAX请求已将正确的true / false发送回我的表单(探查器中的POST参数与我发送的正确)。

Where everything goes sideways, is in the POST_SUBMIT listener. 一切都摆在哪里,在POST_SUBMIT侦听器中。 Through logging this, the $event->getForm()->getData() is always "1" or true. 通过记录此内容, $ event-> getForm()-> getData()始终为“ 1”或true。 According to the docs , this should be the data that currently represents the form. 根据docs ,这应该是当前代表表单的数据。

The checkbox as defined on my form: 在表单上定义的复选框:

$builder->add('businessAcct', CheckboxType::class, array(
    'required' => false,
    'label' => ' ',
    'label_attr' => array(
        'class' => 'middle',
    ),
)) ...

My listener: 我的听众:

$builder->get('businessAcct')->addEventListener(
    FormEvents::POST_SUBMIT,
    function (FormEvent $event) use ($planModifier) {
        $business = $event->getForm()->getData();

        $this->log->info($event->getForm()->getData()); // always produces 1 in profiler

        $planModifier($event->getForm()->getParent(), $business);
    }
);

My $planModifier for completeness ... 我的$ planModifier的完整性...

$planModifier = function (FormInterface $form, bool $business) {
    if ($business) {
        $plans = $this->em->getRepository('AppBundle:Plan')->findAllBusinessPlans();
        $placeholder = '- select business plan -';
    } else {
        $plans = $this->em->getRepository('AppBundle:Plan')->findAllResidentialPlans();
        $placeholder = '- select residential plan -';
    }
    $form->add('plan', EntityType::class, array(
        'class' => 'AppBundle:Plan',
        'choice_label' => 'description',
        'placeholder' => $placeholder,
        'choices' => $plans,
        'label' => 'Plan:',
        'label_attr' => array(
            'class' => 'text-right middle',
        ),
    ));
};

The AJAX code: AJAX代码:

var $bus_acct = $('#businessAcct');
$bus_acct.click(function() {
    var $form = $(this).closest('form');
    var data = {};
    data[$bus_acct.attr('name')] = $bus_acct.is(':checked');
    $.ajax({
        url : $form.attr('action'),
        type: $form.attr('method'),
        data : data,
        success: function(html) {
            $('#plan').replaceWith(
                $(html).find('#plan')
            );
        }
    });
});

I've even tried use $event->getData(), but of course, it didn't work either. 我什至尝试使用$ event-> getData(),但当然也没有用。

I have other dynamic fields on this form, and those work flawlessly. 我在此表单上还有其他动态字段,并且这些字段工作正常。

Any ideas as to why $event->getForm()->getData() is always '1', and not following my businessAcct checkbox? 关于为什么$ event-> getForm()-> getData()始终为“ 1”而不跟随我的businessAcct复选框的任何想法?

Through reading others' issues on this matter, there are two common answers that I found. 通过阅读有关此问题的其他人的问题,我发现了两个常见的答案。

Option 1: Change the CheckboxType into a ChoiceType: 选项1:将CheckboxType更改为ChoiceType:

->add('businessAcct', ChoiceType::class, array(
    'required' => true,
    'choices' => array(
        'Yes' => true,
        'No' => false,
    ),
    'label' => ' ',
    'label_attr' => array(
        'class' => 'middle',
    ),
))

.... Twig edits not shown ....

Option 2: Create a ViewTransformer for the Checkbox: 选项2:为复选框创建一个ViewTransformer:

$builder->get('businessAcct')
    ->addViewTransformer(new CallbackTransformer(
        function ($normalized) {
            return ($normalized);
        },
        function ($submitted) {
            return ($submitted === '__false') ? null : $submitted;
        }
    ))
;

AJAX edit:

data[$bus_acct.attr('name')] = $bus_acct.is(':checked') ? 'true' : '__false';

What is going on here, by using the View Transformer, I'm sending back a string instead of a boolean. 这是怎么回事,通过使用View Transformer,我发回了一个字符串而不是一个布尔值。 This is due to the limitations of browsers sending unchecked checkboxes back to servers. 这是由于浏览器将未选中的复选框发送回服务器的限制。 There is a good read here: https://github.com/symfony/symfony/issues/7139 这里有很好的阅读: https : //github.com/symfony/symfony/issues/7139

I ended up using Option 2. 我最终使用了选项2。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM