How to get value from one picklist depending on value selected from another picklist in Symfony2?

When I select a member from the member list, I need to get his default department from another selected department list in the Add New Member form and, if necessary, change that membership to the selected committee.

I have two objects, member and department. A department is also a property in a member object. Both dropdown lists are populated from the database.

In the FormType.php file I have:

class CommMemberType extends AbstractType

    /**
 * @param FormBuilderInterface $builder
 * @param array $options
 */
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('member','entity', array(
                'label' => 'Member Name',
                'empty_value' => ' ',
                'class' => 'CommitteesBundle:Member',
                'query_builder' => function(EntityRepository $er) {
                    return $er->createQueryBuilder('m')
                        ->orderBy('m.fname', 'ASC');
                },
            )
        )

        ->add('dept', 'entity', array(
            'label' => 'Department',
            'empty_value' => '---Select Department---',
            'required' => true,
            'class' => 'CommitteesBundle:Lookup\Dept',
            'property' => 'meaning',
            'query_builder' => function(EntityRepository $er) {
                return $er->createQueryBuilder('dept')
                    ->orderBy('dept.meaning', 'ASC');
            },
        ));

      

Unfortunately I was unable to find a solution using jQuery to solve this problem. Any help is greatly appreciated!

+3


source to share


1 answer


Unfortunately, this requires a bit of a template.

First, you need to add two events to the form FormEvents::PRE_SET_DATA

and FormEvents::PRE_SUBMIT

to populate the dependent dropdown menu with the appropriate options when submitting the form or entity.

In the example below, the departure dates depend on the selected trip.

class ExampleType extends AbstractType
{
   public function buildForm(FormBuilderInterface $builder, array $options)
   {
        $builder->add('tripsFk', 'entity', array(
            'class'         => 'ExampleBundle:Trips',
            'query_builder' => function(EntityRepository $er) {
                    return $er->createQueryBuilder('t')
                        ->orderBy('t.id', 'DESC');
            },
            'label'       => 'Trip',
            'attr' => array(
                'class' => 'booking_trip'
            )
        ));

        $builder->addEventListener(FormEvents::PRE_SET_DATA, array($this, 'onPreSetData'));
        $builder->addEventListener(FormEvents::PRE_SUBMIT, array($this, 'onPreSubmit'));

    }

    function onPreSubmit(FormEvent $event)
    {
        $form = $event->getForm();
        $data = $event->getData();

        $trip = $data['tripsFk'];
        $this->populateChoices($form, $trip);
    }

    function onPreSetData(FormEvent $event)
    {
        $entity = $event->getData();
        $form = $event->getForm();


        $tripId = $entity->getTripsFk() ? $entity->getTripsFk() : null;

        $this->populateChoices($form, $tripId);
    }

    public function populateChoices($form, $tripId)
    {
        $form->add('departIdFk', 'entity', array(
            'label'         => 'Departure Code',
            'class'         => 'ExampleBundle:Departures',
            'query_builder' => function(EntityRepository $er) use ($tripId) {
                    return $er->createQueryBuilder('t')
                        ->andWhere('t.trip_id', ':trip_id')
                        ->setParameter('trip_id', $tripId);
            },
            'attr' => array(
                'class' => 'booking_date'
            )
        ));
    }
}

      

The next thing you need to do is write javascript that will change the options .booking_date

to shutdown when the path changes. In the js snippet below on .booking_trip

event change, we will remove the existing dispatch options and load the new ones:



var bookingTripChange = (function () {
        var $trip = $('.booking_trip');
        var $dates = $('.booking_date');


        init = function () {
            $trip.on('change', function () {

                $dates.attr('disabled', 'disabled');

                $.ajax({
                    url: Routing.generate('load_departures', {tripId: $trip.val()}),
                    type: 'GET',
                    dataType: 'json',
                    success: function (response) {
                        $dates.find('option').remove();

                        $("<option/>", {value: '', text: 'Specify Departure Code'}).appendTo($dates);

                        $.each(response.tripdates, function (index, entity) {
                            $("<option/>", {value: entity.id, text: entity.label}).appendTo($dates);
                        });

                        $dates.removeAttr('disabled');

                    }
                });
            });
        };
        return {
            init: init
        };
    })();

bookingTripChange.init();

      

The last thing to do is write an action for the route load_departures

. It can be a simple choice with a preset $tripId

and hydrated up to array

.

public function loadChoicesAction(Request $request, $tripId)
{
        $tripdates = $this->getDoctrine()
            ->getRepository('ExampleBundle:Departures')
            ->getTripsDatesOptions($tripId);



        $content = json_encode(array(
            'tripdates' => $tripdates
        ));

        $reponse = new Response($content, 200);

        return $reponse;
}

      

PS

0


source







All Articles