<?php
namespace Acme\DemoBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Acme\DemoBundle\Entity\Person;
use Acme\DemoBundle\Entity\Car;
use Acme\DemoBundle\Entity\Brand;
use Symfony\Component\PropertyAccess\PropertyAccess;
class PersonHasCarType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('brand', 'entity', array(
'class' => 'AcmeDemoBundle:Brand',
'property' => 'name',
'mapped' => false,
'empty_value' => 'Choose a brand',
'attr' => array(
'class' => 'submitOnChange',
)
))
->add('save', 'submit');
$addCars = function($form, $brand) {
if (!empty($brand)) {
$form->add('car', 'entity', array(
'class' => 'AcmeDemoBundle:Car',
'label' => 'Select car',
'query_builder' => function (EntityRepository $er) use ($brand) {
$qb = $er->createQueryBuilder('car');
if ($brand instanceof Brand) {
$qb = $qb->where('car.brand = :brand')
->setParameter('brand', $brand);
}
else if (is_numeric($brand)) {
$qb = $qb->innerJoin('car.brand', 'brand')
->where('brand.id = :id')
->setParameter('id', $brand);
}
return $qb;
},
'empty_value' => 'Choose car',
'position' => array( // requires egeloen/ordered-form-bundle
'after' => 'brand'
),
'property' => 'name',
'validation_groups' => false,
'attr' => array(
'class' => 'clearOnChange'
)
));
}
};
// Below is used in edit modus, when a car is bound to the form, to load car selectbox
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($addCars) {
$data = $event->getData();
$form = $event->getForm();
if (null === $data)
return;
$accessor = PropertyAccess::createPropertyAccessor();
$car = $accessor->getValue($data, 'car');
$brand = ($car) ? $car->getBrand() : null;
$addCars($form, $brand);
});
// Below is used in edit modus, to set the brand selectbox to the right selected value
$builder->addEventListener(FormEvents::POST_SET_DATA, function(FormEvent $event) {
$data = $event->getData();
$form = $event->getForm();
if (null === $data)
return;
$accessor = PropertyAccess::createPropertyAccessor();
$car = $accessor->getValue($data, 'car');
$brand = ($car) ? $car->getBrand() : null;
if ($brand)
$form->get('brand')->setData($brand);
});
// Below is used to load the car selectbox when brand is submitted
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($addCars) {
$form = $event->getForm();
$data = $event->getData();
if (array_key_exists('brand', $data)) {
$addCars($form, $data['brand']);
}
});
}
public function getName() {
return 'acme_demobundle_personhascartype';
}
}