Fabien Potencier
about 1 year ago
Living on the edge
21
In symfony 1.1, we introduced a new form sub-framework. It is a great step forward for symfony, even if the learning curve is a bit steep.
We worked a lot to make it even better for symfony 1.2, and more importantly simpler for newcomers.
One of the form framework strengths is its ability to deal with nested forms. A form can embed a form which in turn can also embed another form (and so on):
$article = ArticlePeer::doSelectOne(new Criteria()); $articleForm = new ArticleForm($article); $authorForm = new AuthorForm($article->getAuthor()); $companyForm = new AuthorForm($article->getAuthor()->getCompany()); $authorForm->embedForm('company', $companyForm); $articleForm->embedForm('author', $authorForm);
The articleForm renders as show below:

Another great feature of the form framework is its ability to automatically
serialize forms. As the forms above are Propel ones, a simple call
to $articleForm->save() will automatically update the $article object with
the submitted and validated values and save it back to the database.
But there was a problem in symfony 1.1. The author and the company
objects were not saved automatically. So, you had to override the save()
method to get the validated data and update the objects manually.
Nothing impossible to do, but really annoying as the form framework
already had all the needed information to make it automatic.
This has been implemented in symfony 1.2 and so will be available with
the upcoming beta 2. That's right, a single call to $form->save() will now update the article,
the author, and the company objects. That's a great news by itself, but there is another one: The new admin generator
also takes this new feature into account.
Comments 
-
#1 Stephen Ostrow said 7 minutes later

I don't know if this stems directly from my post in the groups requesting this or not, but I just wanted to be the first to thank you for this and hope that I'm not the only one helped greatly.
-
#2 Fabien said 10 minutes later

@Stephen Ostrow: I was more than embarrassed by this issue. It was the result of an oversight and I am the very first one to be more than happy that it is fixed now. I am sure it will help a lot of people.
-
#3 pppswing said 13 minutes later

Please, Fabien can you do a tutorial how to do a project with DoctrinePlugin with few classes and explaining the "recommended" practises to build the Database.
Because there are a lot of possibilities with Doctrine and It's easy to get paralyzed.
-
#4 Stephen Ostrow said 19 minutes later

@Fabien: No need to be embarrassed. I think a lot of people were waiting for 1.2 to make the switch, and now that it's getting closer the new framework is going to get a lot more interest. It looks like it will be very useful and save lots of time.
Is it better practice to put the embedForm in the form class or do it in the action. I had found the function initially, but I have it in a new form class and I can't figure out if that's what is causing validation issues.
-
#5 Ken Marfilla said about 1 hour later

How about handling one to many relationship such as Article -> Authors?
-
#6 Éric Rogé said about 1 hour later

Hello Fabien,
This post comes at a perfect time for me, I've tried to use this feature on a brand new project, but I have to deal with an issue that many users may have to face on their own project.
On my Article form, I've added an author embeded form, but only on the purpose to add an new author.
So I have 3 important fields on my form:
- A select field with the existing authors
- A checkbox "Add a new Author" that I've added
- An empty author form, to add a new AuthorHere is the comportment that I want to have :
if "Add a new Author" is checked
I have to desactivate the validator on the existing authors select field
And then save the new Author, and link it to the article
else
I have to desactivate the "new Author" embeded form
And handle the basic existing authors fieldThanks to sfValidatorCallback, I know that I can ADD some custom validators depending on the values submited.
But how can I properly DISABLE some validators depending on the "Add a new author" checked test ?
I know that this comment might seem confused, so here is the form topic that I've created n this subject, with screenshots and source code.
-
#7 Fabien said about 1 hour later

@Stephen Ostrow: It is better to put everything in the form class directly for better reusability.
-
#8 Éric Rogé said about 1 hour later

Oups, I've forgotten to add the link, here it is : http://www.symfony-project.org/forum/index.php/t/16502/
-
#9 sh1ny said about 2 hours later

Is this working for Doctrine forms also ? I can't check it right now.
-
#10 Stephen Ostrow said about 3 hours later

Fabien: That's what I would assume, but that's where i run into validation errors. I'm trying to embed multiples of Form X in Form Y, in your example many Authors in your Article form. Could you add an example of using the naming function for something like that.
sh1ny: Yes this works for Doctrine as well. I've just noticed in 1.1 you have to manually run doctrine:build-forms app. In 1.2 it will automatically build forms, filters, and models while running doctrine:build-all
-
#11 John said about 4 hours later

This is cool and I believe is a much needed feature.
Does this work for merged forms as well? -
#12 Guillaume Chanaud said about 5 hours later

Thank for this ! I had 'lots of fun' with multiple embedded forms in symfony 1.1, i will be definitively be better in 1.2 !
-
#13 Darmen said about 9 hours later

Hi Fabien!
How we can approach this when using Admin Generator? -
#14 Jérôme Vieilledent said about 12 hours later

Great news, thanks !
Will it be possible to dynamically add fields ? For example, when you have to edit an invoice, you can have a variable number of lines which may be added dynamically via JS.
For the moment, in my Symfony 1.1 project, I treat my lines as separate forms and I "link" them with my array of Propel line objects (they are linked with the same array index).
This solution works but it doesn't appear reliable to me. It would be appreciable to have a built in solution for that...
Thx -
#15 Arne said about 12 hours later

well, with sf 1.1 and Doctrine this already worked or not ?
I have used embedded forms and the embedded objects were also saved by doctrine -
#16 Matthias said about 12 hours later

@Arne: this is because Doctrine itself is able to save all related records you add/edit automatically while it seems Propel is not
-
#17 vincent said about 21 hours later

syntax error ?
I think :$companyForm = new AuthorForm($article->getAuthor()->getCompany());
should be :
$companyForm = new CompanyForm($article->getAuthor()->getCompany());
Great feature this nested thing !
-
#18 Haghen said about 23 hours later

Can we use the sfForm's 1.2 implementation into 1.1 symfony's core ?
-
#19 Fabien said 1 day later

@Haghen: Yes, it is possible. But for sfFormPropel to work properly, you will also need to upgrade to Propel 1.3 as some signature have changed.
-
#20 jwage said 1 day later

@sh1ny Yes. This all works the same with Doctrine. I will publish an article that demonstrates all the same functionality very soon.
@Arne Yes this already worked with Doctrine. It was a side affect of how Doctrine handles relationships when using the $object->fromArray() method and propel doesn't.
-
#21 Fabien said 1 day later

@ALL: we will publish a real world example on Monday. So, stay tuned. In the meantime, read the post on Doctrine implementation... Jon did an amazing job so that Propel and Doctrine are now on par.





