0

I am following the Symfony (v2.7) Cookbook recipe for dynamic form modification. What I am aiming for is displaying certain fields based on a user's radio button selection. For example, if a user wishes to filter a search based on records from the last fiscal year, he selects the "Fiscal Year" radio button from the criteriaFilter choice field type (example below), and the appropriate fields are generated. If he changes his mind and selects "Semester" instead, the fiscal year fields are replaced with the semester fields, and so on.

Example code:

$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'
                ),
            ))
            ;

This seems pretty straighforward based on the cookbook entry. However, the form I am creating is not bound to an entity. Therefore, fetching data via the method

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

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

which would normally allow for calling of getter methods on entity properties returns null. So obviously this can't work in this case.

So the question is, is there another way to dynamically generate fields inside of a form that is not tied to an entity?

1 Answer 1

1

You can pass options to the form, including data. So something like (from memory but it's untested):

// 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
        ]);
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

This got me started on my way. I ended up making a preliminary form where the user basically selects the options that are sent along to the actual form. Then I use conditional statements in the event listener to add the fields I want. It's probably not the most elegant solution, but it does the trick well enough.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.