2016-05-10 47 views
0

我遵循的Symfony(v2.7)食谱dynamic form modification食谱。我的目标是根据用户的单选按钮选择显示某些字段。例如,如果用户希望根据上个会计年度的记录过滤搜索,则他会从criteriaFilter选择字段类型(下面的示例)中选择“会计年度”单选按钮,并生成适当的字段。如果他改变主意并选择“学期”,则会将学期字段替换为学期字段,等等。Symfony动态修改表单无实体

示例代码:

$builder  
     ->add('librarian', 'entity', array(
      'class' => 'AppBundle:Staff', 
      'query_builder' => function(EntityRepository $er){ 
       $qb = $er->createQueryBuilder('st'); 
       $qb 
        ->where('st.employmentStatus = :employmentStatus') 
        ->setParameter('employmentStatus', 'faclib') 
        ->orderBy('st.lastName', 'DESC') 
        ->getQuery(); 
       return $qb; 
      }, 
      'placeholder' => 'All Librarians', 
      'required' => false 
     )) 
     ->add('program', 'entity', array(
      'class' => 'AppBundle:LiaisonSubject', 
      'query_builder'=>function(EntityRepository $er){ 
       $qb = $er->createQueryBuilder('ls'); 
       $qb 
       ->orderBy('ls.root, ls.lvl, ls.name', 'ASC') 
       ->getQuery(); 
       return $qb; 
      }, 
      'property' => 'indentedTitle', 
      'placeholder' => 'All Programs', 
      'required' => false, 
      'label' => 'Program' 
     )) 
     ->add('criteriaFilter', 'choice', array(
       'expanded' => true, 
       'multiple' => false, 
       'choices' => array(
        'academic' => 'Academic Year', 
        'fiscal' => 'Fiscal Year', 
        'semester' => 'Semester', 
        'custom' => 'Custom Range' 
       ), 
      )) 
      ; 

这似乎很简单明了基于食谱的条目。但是,我创建的表单并未绑定到实体。因此,通过该方法

$builder->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event){ 
      $form = $event->getForm(); 

      //normally the entity, but NULL in this case 
      $data = $event->getData(); 
... 

其通常允许在实体属性调用的getter方法获取数据返回null。所以显然这在这种情况下无法工作。

所以问题是,是否有另一种方式来动态生成一个表单内的字段不绑定到实体?

回答

1

您可以将选项传递给表单,包括数据。所以像(从内存,但未经测试):

// controller 
$this->createForm(SomeForm::class, null, ['fiscalYears' => [2001, 2002]); 

// type 
public function configureOptions(OptionsResolver $resolver) 
{ 
    $resolver->setDefaults(['fiscalyears' => []); 
} 

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $fiscalYears = $options['fiscalYears']; 

    $builder->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event) use ($fiscalYears) { 
     $form = $event->getForm(); 

     $form->add('fiscalYear', ChoiceType::class, [ 
      'choices' => $fiscalYears 
     ]); 
    } 
} 
+0

这让我开始在我的路上。我最终做出了初步的表格,用户基本上选择了发送给实际表单的选项。然后我在事件监听器中使用条件语句来添加我想要的字段。这可能不是最优雅的解决方案,但它足够好。 – Ravioli87