Embedded forms in symfony are a very useful tool, but ¿how to add them dynamically from the view using AJAX?
Let’s take a simple applicaton. There will be flashcards with a question and its answer. The form for creating these cards could be this:
###With an embedded form
We may want to offer an image as a hint, embedding a PictureForm:
###Dynamic embedded forms
¿What if we are interested in having more than one image as hint, a variable number of them?
In this case we need to write more code. Let’s start with the form (CardForm.class.php in my case):
This code will be valid for new objects (we will embed only a form to start with) and for objects with already embedded pictures.
Now we will write an AddPicture() function that will be very useful:
This function adds a PictureForm to the main form. This is useful for two reasons (we will see this in more detail later):
When adding a picture from an AJAX call, we will call an action that will run this function to obtain a form with the embedded form
. Them, that action will render only what we need. And that will be what we will inject in the view.
When we bind this form, we need the form that is going to be bound to the user-written data to have the right number of embedded pictures. That is, if we are going to bind a user-introduced form with a given number of embedded pictures, the form object must have the same number of embedded forms. For that reason, we will overload the bind function to add as many embedded pictures as we need.
Step by step. First: in the view, we will add this AJAX function. I use Jquery, it is not difficult to write the same thing in Prototype:
And after the form a button to add forms and a place to inject them after the AJAX call:
In the action, we write the this executeAddPicForm() function:
Basically, this function creates a form and calls to addPicture() to have a new form with an embedded form withh the right number. Then we run a partial addPic with this form and the number of embedded form to show. This partial has the following code:
With this we have a button that adds new subforms. But, what about saving? As we said before, we will need bid to do part of the task. Its new code will be:
And with this change we can use this form as a normal one.
PS: I must give people credit about this one. I looked at several places for this info and this post was very useful. It is basically the same, but more focused in adding fields synamically instead of embedded forms.