没有实体的表单的Symfony动态修改

时间:2016-05-10 15:06:05

标签: symfony symfony-forms

我正在关注dynamic form modification的Symfony(v2.7)Cookbook配方。我的目标是根据用户的单选按钮选择显示某些字段。例如,如果用户希望根据上一会计年度的记录过滤搜索,他会选择"会计年度"来自 criteriaFilter 选项字段类型的单选按钮(下面的示例),并生成相应的字段。如果他改变主意并选择" Semester"相反,会计年度字段将替换为学期字段,依此类推。

示例代码:

$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 个答案:

答案 0 :(得分: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
        ]);
    }
}