After many days of trying to figure out the Symfony to Cookbook entry ... http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html
I finally almost got the third example to work with the following code in my ProductType.php file (see below).
When I add a Game there is a corresponding server and category list that come up when I hit the submit button. The new fields only show up if I force an error by putting in invalid input into one of the fields.
I have two questions. If all the data that is not in the $formModifier variable is valid it submits the data and I do not see the "Server", and "Category" choices. How do I make sure 'server' and 'category' are required even though I do not need them to show up until the Game is selected.
The second question is in the cookbook entry it says "One piece that may still be missing is the client-side updating of your form after the sport is selected. This should be handled by making an AJAX call back to your application. In that controller, you can submit your form, but instead of processing it, simply use the submitted form to render the updated fields."
Since my event modifier is on "Submit" how do I submit to a controller entry with the selected game (id) and only render the fields that are only required after the game is selected?
Thanks in Advance.
Scott
<?php
namespace Acme\MainBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\FormInterface;
use Acme\MainBundle\Entity\Game;
class ProductsType extends AbstractType {
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('name')
->add('price')
->add('description')
->add('game')
;
// ** Build Form Interface Based On Selected Game **//
$formModifier = function(FormInterface $form, Game $game, $game_id) {
// ** Add Servers Based On Game Id ** //
$form->add('server', 'entity', array(
'class' => 'Acme\MainBundle\Entity\GameServers',
'query_builder' => function(EntityRepository $er) use ($game_id) {
$query = $er->createQueryBuilder('i')
->select(array('i'))
->where('i.game_id = :game_id')
->setParameter('game_id', $game_id)
->orderBy('i.name', 'ASC');
return $query;
},
)
);
// ** Build Category List Based on Game Id Submitted ** //
// Refactor this so that is nothing is selected that it Doesn't Build Category List **/
$form->add('category', 'entity', array(
'class' => 'Acme\MainBundle\Entity\GameCategories',
'query_builder' => function(EntityRepository $er) use ($game_id) {
$query = $er->createQueryBuilder('i')
->select(array('i'))
->where('i.game_id = :game_id')
->setParameter('game_id', $game_id)
->orderBy('i.name', 'ASC');
return $query;
},
)
);
};
//** Checks for Games That Are Submitted and Adds Servers and Categories Based on Game Selection **//
$builder->get('game')->addEventListener(
FormEvents::POST_SUBMIT, function(FormEvent $event) use ($formModifier) {
// Get Form Data to Pass Back to Modifier
$game = $event->getForm()->getData();
// Get Game Id to pass back to Form Modifier
$game_id = $event->getForm()->getData()->getId();
$formModifier($event->getForm()->getParent(), $game, $game_id);
}
);
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'data_class' => 'Acme\MainBundle\Entity\Products'
));
}
/**
* @return string
*/
public function getName() {
return 'acme_mainbundle_products';
}
}