2016-07-27 57 views
1

我希望能夠動態添加實體,而不需要在EntityType表單類型的選項選項中預設它們。我需要修改可用選項,否則會彈出invalid value錯誤。動態修改表單預設選項以通過symfony2中的驗證

class MyImageType extends AbstractType { 
    public function __construct($em) { 
     $this->em = $em; 
    } 

    public function configureOptions(OptionsResolver $resolver) { 
     $resolver->setDefaults(array(
      'class' => 'stuff/MyImage', 
      'choice_label' => 'id', 
      'multiple' => true, 
      'choices' => [], 
     )); 
    } 

    public function buildForm(FormBuilderInterface $builder, array $options) { 
     // 
    } 

    public function getParent() { 
     return EntityType::class; 
    } 
} 

,我使用它是這樣的:

$builder->add('images', 'stuff\MyImage\Form\Type\MyImageType') 

的HTML生成這個樣子的:

<select id="product_images" name="product[images][]" required="required" class="form-control" multiple="multiple"> 
</select> 

我執行一些Ajax調用創建實體和追加id到下拉如下:

<select id="product_images" name="product[images][]" required="required" class="form-control" multiple="multiple"> 
    <option value="88" selected="selected">88</option> 
</select> 

88是現有實體的現有ID。

如果我之後提交表格,則會出現invalid value錯誤,因爲88不在此實體類型的預設choices中。所以我需要在可用的選項中添加88

如果這是一個形式(Symfony的\分量\表\表)的孩子,我能做到這一點上FormEvents::PRE_SUBMIT

//.. 
$img = $em->findOneById(88); 
$form->add('images', [ 
    'class' => 'stuff/MyImage', 
    'choice_label' => 'id', 
    'multiple' => true, 
    'choices' => [$img], 
]); 

但在我的情況下,我想這樣做,裏面MyImageType類來封裝類。你可以給我指導如何做到這一點?謝謝。

編輯:

在寫這個問題我已經找到了解決這一進程。在事件中,我可以更新場像這樣:

$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use($em) { 
    $form = $$event->getForm(); 
    $form->getParent()->add('images', EntityType::class, $options); 
} 

不過我不想回答我的問題,因爲也許有更好的方式來做到這一點。謝謝。

+0

您是否在將對象的設置方法傳遞給表單之前嘗試設置值? – DOZ

+0

我剛纔提出了一個類似的解決方案給一個像你這樣的問題的用戶。 http://stackoverflow.com/questions/27981609/symfony-adding-element-to-form-collection-in-pre-submit-event/27982025#comment44356045_27982025 –

回答

0

看看我的FormBundle

爲了解決這個問題,我鉤住了PRE_SUBMIT FormEvent,然後我重新創建了將注入提交的選項的子注入新的「選擇」選項。

如果您希望在編輯實體時填充字段,則必須在PRE_SET_DATA中執行相同的操作。

注意

這樣做會這樣,每個現有的提交實體將是一個有效的值。 如果只有一部分實體可選,則還應該爲您的字段添加一個約束。