1

I am trying to set up an ajax call to to fill the select option for user.

1/ You select location

2/ new dropdown appear with zone

Everything work just fine until :

3/ Validation form does not pass

Unable to reverse value for property path "zone":

The choice "13e Arrondissement" does not exist or is not unique

FormType:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    //...

     ->add('location', EntityType::class, ['class' => 'PagesBundle:City'])
     ->add('zone', CoreType\ChoiceType::class, ['choices_as_values' => true, 'mapped' => false]);

    $builder->get('zone')->addEventListener( FormEvents::PRE_SET_DATA, function (FormEvent $event) {
            $form = $event->getForm()->getParent();
            $data = $event->getData();
            $city[$data] = $data;

            $form->add('zone', CoreType\ChoiceType::class, ['choices' => $city,'choices_as_values' => true]);

        //...     

My Ajax :

$("document").ready(function() { 
$('#zone').addClass('uk-hidden');
$("#cityName").change(function() {
    var city = $( "#owner_location option:selected" ).text();

       $.ajax({
          type: 'GET',
          url: 'http://locavip.dev/app_dev.php/owner/city/' + city,

          beforeSend: function(){
            $('#owner_zone option').remove();
          },

          success: function(data) {

             $.each(data.zone, function(index, value){
                $('#zone').removeClass('uk-hidden');
                $("#owner_zone").append($('<option>', { value : value, text: value }));
             });
          }
       });

}); });

AjaxController:

$em = $this->getDoctrine()->getManager();
        $database = 'PagesBundle:'.$city;
        $cityName = $em->getRepository($database)->findAll();   

        foreach ($cityName as $value) {
                $cities[] = $value->getZone();
        }
        $response = new JsonResponse();

        return $response->setData(array('zone' => $cities));

Thanks

1 Answer 1

1

I have found the solution.

For my ajax field "ZONE" i first use ChoiceType::class, then on PRE_SUBMIT i retrieve user data from "ZONE" and i modify my field to to TextType::class then i use "getData()" option to set the right data before inserting into DB.

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('type', ApxType\TypeType::class, ['expanded' => true, 'multiple' => false,'label' => false])
        ->add('room', ApxType\NbRoomType::class,['expanded' => true, 'multiple' => false,'label' => false])
        ->add('rent', CoreType\NumberType::class,['label' => false])
        ->add('area', CoreType\NumberType::class,['label' => false])
        ->add('images', CoreType\CollectionType::class, [
                            'entry_type' => ImagesFlatType::class,
                            'allow_add' => true,
                            'required' => false,
                            'allow_delete' => true,
                            'label' => false,
                            'by_reference' => false,
                            ])

        ->add('transport', CoreType\TextType::class,['label' => false, 'required' => false])
        ->add('furnished', ApxType\FurnishedType::class, ['expanded' => true, 'multiple' => false,'label' => false])
        ->add('vip', ApxType\LesVipType::class, ['expanded' => true, 'multiple' => true,'label' => false])
        ->add('feature', ApxType\FeatureType::class, ['expanded' => true, 'multiple' => true,'label' => false])
        ->add('description', CoreType\TextareaType::class,['label' => false, 'required' => false])

        // City with ajax call  in register.js
        ->add('location', EntityType::class, ['class' => 'PagesBundle:City', 'placeholder' => 'Selectionner une ville'])
        ->add('zone', CoreType\ChoiceType::class, ['mapped' => false, 'choices_as_values' => true]);

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

    $builder->getForm();
}
/**
 * Check if user is login
 * Add field accordingly 
 * 
 */
public function onPreSetData(FormEvent $event)
{
    $user = $this->tokenStorage->getToken()->getUser();
    $form = $event->getForm();

    if (!is_object($user)) 
    {
        $form->add('user', UsersType::class, ['label' => false])
                ->add('corporate', ApxType\CorporateType::class, ['expanded' => true,
                                                                    'multiple' => false,
                                                                    'label' => false])
                ->add('fee', CoreType\NumberType::class, ['label' => false, 'required' => false]);
    }

    if(is_object($user))
    {
        foreach($user->getOwner() as $value)
        {
            if($value->getCorporate() === 'agence')
            {
                $form->add('fee', CoreType\NumberType::class, ['label' => false, 'required' => false]);
            }
        }   
    }
}

/**
 * Change field type and populate database 
 * 
 */
public function onPreSubmit(FormEvent $event)
{
    $form = $event->getForm();
    $data = $event->getData();

    if(!array_key_exists('zone', $data))
    {
        foreach($user->getOwner() as $value)
        {
            $data['zone'] = $value->getZone();
        }

    }

    $city = $data['zone'];

    $form->add('zone', CoreType\TextType::class, ['data' => $city]);
}
Sign up to request clarification or add additional context in comments.

Comments

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.