我有一个表单,我使用复选框来过滤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复选框?
答案 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。