Symfony3动态表单复选框

时间:2017-10-06 23:23:22

标签: php ajax dynamic symfony-3.3

我有一个表单,我使用复选框来过滤EntityType。首次呈现表单时,将取消选中该复选框(false)。当我检查它时,它会正确触发我的AJAX,并且我的实体会使用正确的子集进行更新。

然而,当我取消选中该复选框时,新实体仍然存在。

在浏览代码时,我已经验证了AJAX请求正在向我的表单发送正确的true / false(探查器中的POST参数与我发送的内容相符)。

一切都在横向,在POST_SUBMIT监听器中。通过记录此操作, $ event-> getForm() - > getData()始终为“1”或true。根据{{​​3}},这应该是当前代表表单的数据。

我的表单中定义的复选框:

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

我的听众:

$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);
    }
);

我的$ 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',
        ),
    ));
};

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

我甚至尝试过使用$ event-> getData(),但当然,它也没有用。

我在这个表单上有其他动态字段,这些字段完美无缺。

为什么 $ event-> getForm() - > getData()的任何想法始终为'1',而不是关注我的businessAcct复选框?

1 个答案:

答案 0 :(得分:1)

通过阅读其他人'关于这件事的问题,我找到了两个常见的答案。

选项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 ....

选项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';

这里发生了什么,通过使用View Transformer,我发回一个字符串而不是一个布尔值。这是由于浏览器将未经检查的复选框发送回服务器的限制。这里有一个很好的解读:https://github.com/symfony/symfony/issues/7139

我最终使用了选项2。