2013-11-29 27 views
1

後試圖弄清楚的Symfony到菜譜進入多天...... http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html最終處理Symfony2的動態表單修改

我終於差點第三個例子,我ProductType.php文件,下面的代碼工作(見下文)。

當我添加一個遊戲時,有一個相應的服務器和類別列表,當我點擊提交按鈕時出現。如果我通過將無效輸入放入其中一個字段來強制執行錯誤,則只會顯示新字段。

我有兩個問題。如果所有不在$ formModifier變量中的數據都是有效的,它會提交數據,而我看不到「服務器」和「類別」選項。我如何確保'服務器'和'類別'是必需的,即使我不需要它們在選擇遊戲之前出現。

第二個問題是在食譜條目中它說:「一件事情可能仍然是你選擇運動後你的表單的客戶端更新,這應該通過嚮應用程序發回一個AJAX調用來處理。在該控制器中,您可以提交表單,但不是處理它,只需使用提交的表單來呈現更新的字段。「

由於我的事件修飾符位於「提交」上,我如何使用所選遊戲(id)提交給控制器條目,並且只渲染僅在遊戲被選中後才需要的字段?

在此先感謝。

斯科特

<?php 

namespace Acme\MainBundle\Form; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolverInterface; 
use Symfony\Component\Form\FormEvent; 
use Symfony\Component\Form\FormEvents; 
use Doctrine\ORM\EntityRepository; 
use Symfony\Component\Form\FormInterface; 
use Acme\MainBundle\Entity\Game; 

class ProductsType extends AbstractType { 

    /** 
    * @param FormBuilderInterface $builder 
    * @param array $options 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) { 
     $builder 
       ->add('name') 
       ->add('price') 
       ->add('description') 
       ->add('game') 

     ; 

     // ** Build Form Interface Based On Selected Game **// 

     $formModifier = function(FormInterface $form, Game $game, $game_id) { 

        // ** Add Servers Based On Game Id ** // 
        $form->add('server', 'entity', array(
         'class' => 'Acme\MainBundle\Entity\GameServers', 
         'query_builder' => function(EntityRepository $er) use ($game_id) { 
          $query = $er->createQueryBuilder('i') 
            ->select(array('i')) 
            ->where('i.game_id = :game_id') 
            ->setParameter('game_id', $game_id) 
            ->orderBy('i.name', 'ASC'); 
          return $query; 
         }, 
          ) 
        ); 
        // ** Build Category List Based on Game Id Submitted ** // 
        // Refactor this so that is nothing is selected that it Doesn't Build Category List **/   
        $form->add('category', 'entity', array(
         'class' => 'Acme\MainBundle\Entity\GameCategories', 
         'query_builder' => function(EntityRepository $er) use ($game_id) { 
          $query = $er->createQueryBuilder('i') 
            ->select(array('i')) 
            ->where('i.game_id = :game_id') 
            ->setParameter('game_id', $game_id) 
            ->orderBy('i.name', 'ASC'); 

          return $query; 
         }, 
          ) 
        ); 
       }; 

     //** Checks for Games That Are Submitted and Adds Servers and Categories Based on Game Selection **// 
     $builder->get('game')->addEventListener(
       FormEvents::POST_SUBMIT, function(FormEvent $event) use ($formModifier) { 
        // Get Form Data to Pass Back to Modifier 
        $game = $event->getForm()->getData(); 
        // Get Game Id to pass back to Form Modifier 
        $game_id = $event->getForm()->getData()->getId(); 
        $formModifier($event->getForm()->getParent(), $game, $game_id); 
       } 
     ); 
    } 

    /** 
    * @param OptionsResolverInterface $resolver 
    */ 
    public function setDefaultOptions(OptionsResolverInterface $resolver) { 
     $resolver->setDefaults(array(
      'data_class' => 'Acme\MainBundle\Entity\Products' 
     )); 
    } 

    /** 
    * @return string 
    */ 
    public function getName() { 
     return 'acme_mainbundle_products'; 
    } 

} 

回答

1

我已經找到了答案,AJAX部分與該SO進入How to handle Ajax forms with collections in Symfony2.3

這是我實現

的JavaScript

$(document).ready(function() { 
    $('#acme_mainbundle_products_game').change(function(){ 
     if($(this).val()){ 
      $.ajax({ 
     type: "POST", 
     url: "{{ url('productsCreateSubmit') }}", 
     data: $(this).serialize(), 
     success: function(data) { 
      $('#dynamic_fields').html(data); 
     } 
    }); 

    return false; 
     } 
    }); 
}); 

twig in /new.html.twig

{%extends' :: base.html.twig」%}

{%塊體 - %}

<h1>Products creation</h1> 
    {{ form_start(form) }} 
    <hr /> 
     {{ form_label(form.name) }} 
     {{ form_errors(form.name) }} 
     {{ form_widget(form.name) }} 
    <hr /> 
     {{ form_label(form.price) }} 
     {{ form_errors(form.price) }} 
     {{ form_widget(form.price) }} 
    <hr /> 
     {{ form_label(form.description) }} 
     {{ form_errors(form.description) }} 
     {{ form_widget(form.description) }} 
    <hr /> 
     {{ form_label(form.game) }} 
     {{ form_errors(form.game) }} 
     {{ form_widget(form.game) }} 
    <hr /> 
    <div id="dynamic_fields">Stuff Will Go Here</div> 
{{ form_end(form) }} 

serverslist.twig.html

<hr /> 
{{ form_label(form.server) }} 
{{ form_errors(form.server) }} 
{{ form_widget(form.server) }} 
<hr /> 
<hr /> 
{{ form_label(form.category) }} 
{{ form_errors(form.category) }} 
{{ form_widget(form.category) }} 
<hr /> 

,最後控制器條目

/** 
* @Route("/products/create/submit", name="productsCreateSubmit") 
*/ 
public function productsCreateSubmitAction(Request $request) { 
    $products = new Products(); 

    $form = $this->createForm(new ProductsType(), $products); 
    $form->handleRequest($request); 

    return $this->render('AcmeMainBundle:Products:serverslist.html.twig', array(
       'form' => $form->createView(), 
    )); 
} 

我仍然需要完成驗證,但這是我如何做ajax只呈現必填字段。這似乎是正確的,它的工作原理,但如果任何人有任何反饋,如何做得更好,我很樂意聽到反饋。

0

我覺得那裏有錯的財產以後,當越來越$遊戲對象使用這樣的:

//** Checks for Games That Are Submitted and Adds Servers and Categories Based on Game Selection **// 
    $builder->get('game')->addEventListener(
      FormEvents::POST_SUBMIT, function(FormEvent $event) use ($formModifier) { 
       // Get Form Data to Pass Back to Modifier 
       $game = $event->getForm()->getData()->getGame(); 
       // Get Game Id to pass back to Form Modifier 
       $game_id = $game->getId(); 
       $formModifier($event->getForm()->getParent(), $game, $game_id); 
      } 
    ); 

,你不使用$遊戲對象,你只能使用$ game_id $ formModifier。這樣你就可以改變你的功能是這樣的:

$formModifier = function(FormInterface $form, $game_id) { 
    //Adding other widgets here 
} 
+0

謝謝你,我做了這個改變,你是正確的,但這不是真正的問題。問題是當字段最初沒有出現時的驗證以及如何僅基於遊戲ID呈現提交的新字段。 – smugford