2

My app contains a form with three choice fields / dropdown lists.

The first is linked to a "relational" field in the entity, and works fine. The user is supposed to choose a table link first.

The second and third are both linked to string fields in that same entity. Through jQuery, these choice fields get populated with values based on the decision the user makes in the first dropdown list.

After submitting the form, there is an error for the second and third field: they contain invalid input. When I check the form object, their values were not bound; their values never arrived.

The choice fields for collecting string data from the user looks like this:

->add('sourceName', 'choice', array
    (
        'label' => 'Choose source name:',
        'empty_value' => 'Please choose a table link first...',
        'choices' => array(),
        'attr' => array('class' => 'extFieldChoice'),
    )

After jQuery has done its job, the html select element looks like this:

<select id="someId" name="someName[sourceName]" required="required" 
  class="extFieldChoice">
  <option value="first">first</option>
  <option value="second">second</option>
  <option value="manymore">Many more...</option>
</select>

I suspect that the error can be found in the initially empty choices array. However, it would be impossible to fill it with all possible choices, because they run in the hundreds.

1 Answer 1

3

I've the same problem few days ago and it drive me nuts to find a solution, I get to this question and even probably it's too late I want to share the solutions I've found in case there'll be someone with the same problem, I have found three of them, but none of them seems to be the perfect solution.

In my case I have to save the city selected by an user based on the zipCode. When a user save a new address he wrotes the zipCode and then via ajax I fill-in the city select with options of the cities.

My "choice" field declaration:

$builder->add('city', 'choice', array(
    'label' => 'form.city',
    'read_only' => true,
    'mapped' => false,
    'required' => false,
    'empty_value' => false,
    'choices' => array('none' => 'form.empty.city'),
    'data' => null
));

The problem is that the form validation look for two things:

  1. If the form it's related with an entity looks forward the entity to validate, you can skip this validation easily with the "mapped" => false parameter.
  2. The form validation itself, if you have a "choice" type field with or without choices defined when the form validate look towards the first choices you have declared. And I haven't been able to skip the validation for only this field.

So the three ways I have found:

  1. Use the form event and before whe bind the request to the form $builder->addEventListener(FormEvents::PRE_BIND, function (DataEvent $event) use ($xxx) { ...}); (I have an example of use at the linked article) we make the same query to the database we have made on the ajax, we retrieve the values and add them to the chocie field. This is the better way if we think in code, but we have to do the same query twice, and I don't want to do that.
  2. In my case I have to store a string with the city name so another option is to add the city field as a hidden one and insert the whole select as an element. But I don't like this one for many reasons, two of them: I don't like the idea of insert a hole , with and between the other form fields created by symfony2; the other one is that it requires more jquery that it's necessary from my point of view.
  3. Based on the second option, I was filling in some other hidden fields based on the city selection the user has made, so I only include one more hidden field to save the city name; and when the form is submited I remove all the options from the select, so it matches the choices I have defined.

    $('#cityChoice').on({
        change: function(){
            var optionSelected = $(this).find('option:selected');
            $('#city').val(optionSelected.val());
            $('#latitude').val(optionSelected.data('lat'));
            $('#longitude').val(optionSelected.data('lng'));
        }
    });
    
    $('#myForm').on({
        submit: function(){
            $('#mySelect option').remove();
        }
    });
    

I've decided for the third option, but I think the three of them have bad sides.

Sign up to request clarification or add additional context in comments.

1 Comment

So in symfony 4 i had problem that i had array like ['string'=>'string'] the only thing that worked for me was: "data" => false,. Do not add "mapped" => false, with this i had string saved in database but only the one i had set as default in entity.

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.