2017-10-06 91 views
0

我有一个窗体,我使用复选框来过滤EntityType。当表单第一次呈现时,复选框未被选中(false)。当我检查它时,它正确地激发了我的AJAX,并且我的实体更新了正确的子集。Symfony3动态表单复选框

但是,当我然后去取消复选框,新的实体仍然存在。

虽然通过代码,我已经验证了AJAX请求发送适当的真/假返回到我的表单(探查器中的POST参数对我发送的内容是正确的)。

凡是横向排列的地方,都在POST_SUBMIT监听器中。通过记录这一点,$ event-> getForm() - > getData()始终为“1”或true。根据docs,这应该是当前代表该表格的数据。

我的表格上定义的复选框:

$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

党...我想我做的还不够搜索。显然,这是一个已知的问题。 [https://github.com/symfony/symfony/issues/7139](https://github.com/symfony/symfony/issues/7139) – profm2

回答

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