Autor wpisu: Kamil Adryjanek, dodany: 20.10.2012 13:27, tagi: symfony2, php
Today i would like to share my recent experience on forms and data dependent fields. Playing with Symfony2 forms some time ago i was looking for best solutions of adding fields to forms that depend on the data / Doctrine object – there was nothing about it in the official Symfony documentation. I thought, as many other developers that the best / easiest way is to pass the current object in form constuctor. Today i know it was wrong but what is the recommended solution? Is there any easy way to add / remove form fields?
Imagine a scenario:
- simple user management
- we want to
buy viagra online without a prescription
add add / edit users and their properties.
- user properties depend on user
Implementing form in the old way i will write code:
<?php namespace My\AdminBundle\Form; use My\AdminBundle\Entity\User; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolverInterface; class UserType extends AbstractType { protected $user = null; public function __construct(User $user) { $this->user = $user; } public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('firstName', 'text', array('label' => 'First name')) ->add('lastName', 'text', array('label' => 'Last name')) ->add('email', 'email', array('label' => 'Email address')) ; // add permissions for none admin users if (!$this->user->isAdmin()) { $builder ->add('permissions', 'entity', array( 'label' => 'Access Permisson', 'class' => 'AdminBundle:Permission', 'multiple' => true, 'expanded' => true )) } } public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'data_class' => 'My\AdminBundle\Entity\User' )); } public function getName() { return 'my_adminbundle_usertype'; } }
But according to Bernhard Schussek the recommended way of playing with dependent fields in Symfony forms is to add / remove fields using EventListeneres on form events. Using FormEvent we can access our data object ($event->getData()), current form ($event->getForm()) and determine which fields add or remove accoridng to User object.
Yes, it may seem a bit complicated but i will try to show it in UserType example:
<?php namespace My\AdminBundle\Form; use My\AdminBundle\Entity\User; use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvents; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolverInterface; class UserType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('firstName', 'text', array('label' => 'First name')) ->add('lastName', 'text', array('label' => 'Last name')) ->add('email', 'email', array('label' => 'Email address')) ; $formFactory = $builder->getFormFactory(); // add permissions for none admin users $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($formFactory) { if (!$event->getData()->isAdmin()) { $event->getForm()->add($formFactory->createNamed( 'permissions', 'entity', null, array( 'label' => 'Access Permisson', 'class' => 'AdminBundle:Permission"', 'multiple' => true, 'expanded' => true ))); } } ); } public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'data_class' => 'My\AdminBundle\Entity\User' )); } public function getName() { return 'my_adminbundle_usertype'; } }
Maybe it’s better, maybe it’s recommended way of adding dependent fields but in my opinion it also quite complicated. What about forms where we have many dependent fields? It’s a lot of code just for one filed. It really needs simplification. list of online casinos