1
votes

I have 2 entities:

class Exercise
{
//entity
} 

and

class Question
{
//entity
}

Their relationship is ManyToMany. The question is: How I can filter (on the exercise form) the Question entities?

I have this form for Exercise:

public function buildForm(FormBuilderInterface $builder, array  $options)
{
$builder
    ->add('questions', null, array(
        'property' => 'name',
        'multiple' => true,
        'expanded' => false,
        'query_builder' => function(EntityRepository $er) use ($options) {
         return $er->createQueryBuilder('u') 
         ->where('u.level = :level')
         ->setParameter('level',$options['level'])
         ->orderBy('u.dateR', 'ASC');},
        ))
        //other fields
        ->add('Save','submit')
    ;
}

I know that I can filter with the query_builder but, how I can pass the var $search? Should I create another form?

Any help would be appreciated. Best regards

EDIT: I have found the solution that I want. I put 2 forms on the Controller Action, one form for the entity and one form for filter.

//ExerciseController.php
public function FormAction($level=null)
{

    $request = $this->getRequest();
    $exercise  = new Exercise();

    //Exercise form    
    $form = $this->createForm(new ExerciseType(), $exercise,array('level' => $level));

    //create filter form
    $filterForm = $this->createFormBuilder(null)
        ->add('level', 'choice', array('choices' => array('1'   => '1','2' => '2','3' => '3')))
        ->add('filter','submit')
        ->getForm();

    //Manage forms
    if($request->getMethod() == 'POST'){
    $form->bind($request);
    $filterForm->bind($request);

    //If exercise form is received, save it.
    if ($form->isValid() && $form->get('Save')->isClicked()) {
        $em = $this->getDoctrine()->getManager();
        $em->persist($exercise);
        $em->flush();

                return $this->redirect($this->generateUrl('mybundle_exercise_id', array('id' => $exercise->getId())));                    
    }

    //If filter form is received, filter and call again the main form.
    if ($filterForm->isValid()) {
        $filterData = $formFiltro->getData();


   $form = $this->createForm(new ExerciseType(), $exercise,array('level' => $filterData['level']));

   return $this->render('MyBundle:Exercise:crear.html.twig', array(
        'ejercicio' => $ejercicio,
        'form'   => $form->createView(),
        'formFiltro' => $formFiltro->createView(),
    ));

            }

    }

    return $this->render('juanluisromanCslmBundle:Ejercicio:form.html.twig', array(
        'exercise' => $exercise,
        'form'   => $form->createView(),
        'formFiltro' => $filterForm->createView(),
    ));
}

Templating the forms On the form.html.twig

{{ form_start(filterForm) }}
{{ form_errors(filterForm) }}
{{ form_end(filterForm) }}

{{ form_start(form) }}
{{ form_errors(form) }}
{{ form_end(form) }}

It works for me and it is that i was looking for.

1

1 Answers

0
votes

What you probably want to do here, is to make use of the form builder:

 $search = [...]
 $form = $this->createForm(new AbstractType(), $bindedEntityOrNull, array(
        'search' => $search,
    ));

here you can provide any list of arguments to the builder method of your AbstractType.

public function buildForm(FormBuilderInterface $builder, array  $options)

as you may have guessed at this point you may access the options array throu the $option variable.


As a side note remember to provide a fallback inside the default option array. In your AbstractType you can do something like this:

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'search' => 'some_valid_default_value_if_search_is_not_provided'
    ));
}

hope it helps, regards.