2015-07-11 35 views
0

我有一個描述封裝的symfony的2形式:Symfony2的形式的問題,增加一個動態字段

class PackageType extends AbstractType 
{ 
    /** 
    * @param FormBuilderInterface $builder 
    * @param array $options 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->setMethod('POST') 
      ->add('deliveryNote') 
      ->add('receiver', new ReceiverType()); 

     // field stockitem exists, added dynamically NOT good 

    } 

    /** 
    * @param OptionsResolverInterface $resolver 
    */ 
    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'IREnterprise\AppBundle\Entity\Package', 
      'csrf_protection' => false, 
      'allow_extra_fields' => true 
     )); 
    } 

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

每個包都有1個接收器,並且與該包相關聯的包線動態量,每包裝線包含一個stockitem。

這個想法是,用戶可以添加現有的StockItems,作爲包裝線。

我已經實現了這一點,它看起來是這樣的:在用戶每次點擊addPackageLine包線被添加到形式,他可以選擇一個stockItem和stockItem的時間量 enter image description here

無論如何,我不得不做一些瑣碎的事情繞過formBuilder。

那麼控制器結束這樣看:

public function newPackageAction(Request $request) 
{ 
    $package = new Package(); 
    $form = $this->createForm(new PackageType(), $package); 
    $form->handleRequest($request); 

    // Test if stock item belongs to user, and add to package 
    $formStockItems = $request->request->get('IREnterprise_AppBundle_package[stockItems]', null, true); 

    // This is bad ... very bad, should be a doctrine validation 
    if (empty($formStockItems)) { 
     $form->add('packageLines')->addError(new FormError('Package Lines cannot be null')); 
    } 


    if ($form->isValid()) { 

     $em = $this->getDoctrine()->getManager(); 

     $package->setUser($this->getUser()); 

     foreach ($formStockItems as $formStockItem) { 
      $stockItem = $em->getRepository('IREnterpriseAppBundle:StockItem') 
       ->findByUserAndId($this->getUser(), $formStockItem['item']); 

      if (!empty($stockItem)) { 

       // Create a package line for the stock item, and add it the line to the package 
       $packageLine = new PackageLine(); 
       $packageLine->setStockItem($stockItem); 
       $packageLine->setAmount($formStockItem['quantity']); 
       $packageLine->setPackage($package); 

       $package->addPackageLine($packageLine); 
      } 
     } 

     $em->persist($package); 
     $em->flush(); 

     $response = View::create($package); 
     return $response; 
    } 

    return View::create($form, Response::HTTP_BAD_REQUEST); 

} 

我想這樣做是不太hackish的方式,使形式 - > isValid()的也驗證所有的packageLiens一起發送,因爲我表單錯誤會被這種方法搞砸了,有什麼建議嗎?

+0

我只是掠過你的問題,但有一個「原型」的表單字段查看[Form Events](http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html)和[Form Collections](http://symfony.com/doc/current/cookbook/)的文檔form/form_collections.html),我認爲其中的一些可能適用。 –

回答

1

在交響樂中使用「集合」表單類型。有關完整的詳細信息,請參閱How to Embed a Collection of Forms文檔,但基本知識是集合類型採用「類型」選項,該選項指定集合中每個元素的表單類型。

您還可以指定「allow_add」和「allow_delete」選項以允許動態調整大小。

使用「allow_add」還使一個方法來創建可以由你的JavaScript用來渲染的新項目的形式,這個集合