Update for Symfony 3.x: See this comment to see the changes needed.

 

Symfony forms are quite horrible when you want to do custom things (like javascript, autocomplete, and collections or both 🙂 ). There are some solutions available on the internet, but they often “hack” the symfony form using DataTransformers and text fields.

I think we found the right way to create a working javascript autocomplete mapped to a Symfony form.

The models

Let’s assume we have an Article class, which may be written by a list of User. The classes will look like this:

 

The javascript part

I will not show example on the javascript part because there are already many solutions on the internet. The solution we use is pretty “basic”, we call an url showing a list of items, we create a new item having the right name for symfony ( ex: < <label> <input type="checkbox" name="my_form[user][]" val="id" /> title <label>  )

The Symfony form part

The big tweak between is to NOT include your “userList” in the buildForm method, but to delay this addition in an FormEvent PRE_SET_DATA. This way, you can list the current userList of the article (if any).

The User collection form type

 

The Article form

 

Explanations

The “preSetData” method will be called before the data normalizations.

The “preSubmit” event is only called on the submission of the form. It is necessary, because if you only use the preSetData, the “choices” will be a small subset of your database, and if you add a user, he will not be in the choices, so Symfony will throw an error.

The solution here is to pass the id passed before the submission, and use in this case the “query_builder” option to still validate that the id exists in the database.

 

 

That’s it !

 

Featured images taken from hakim.se checkwave