2017-10-06 98 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