-
-
Save jaytaph/9640066 to your computer and use it in GitHub Desktop.
| <?php | |
| namespace NoxLogic\DemoBundle\Entity; | |
| use Doctrine\ORM\Mapping as ORM; | |
| /** | |
| * Account | |
| * | |
| * @ORM\Table() | |
| * @ORM\Entity() | |
| */ | |
| class Account | |
| { | |
| /** | |
| * @var integer | |
| * | |
| * @ORM\Column(name="id", type="integer") | |
| * @ORM\Id | |
| * @ORM\GeneratedValue(strategy="AUTO") | |
| */ | |
| private $id; | |
| /** | |
| * @var string | |
| * | |
| * @ORM\Column(name="name", type="string", length=255) | |
| */ | |
| private $name; | |
| /** | |
| * @ORM\ManyToOne(targetEntity="City") | |
| */ | |
| protected $city; | |
| /** | |
| * Get id | |
| * | |
| * @return integer | |
| */ | |
| public function getId() | |
| { | |
| return $this->id; | |
| } | |
| /** | |
| * Set name | |
| * | |
| * @param string $name | |
| * @return Account | |
| */ | |
| public function setName($name) | |
| { | |
| $this->name = $name; | |
| return $this; | |
| } | |
| /** | |
| * Get name | |
| * | |
| * @return string | |
| */ | |
| public function getName() | |
| { | |
| return $this->name; | |
| } | |
| /** | |
| * Set city | |
| * | |
| * @param \NoxLogic\DemoBundle\Entity\City $city | |
| * @return Account | |
| */ | |
| public function setCity(\NoxLogic\DemoBundle\Entity\City $city = null) | |
| { | |
| $this->city = $city; | |
| return $this; | |
| } | |
| /** | |
| * Get city | |
| * | |
| * @return \NoxLogic\DemoBundle\Entity\City | |
| */ | |
| public function getCity() | |
| { | |
| return $this->city; | |
| } | |
| } |
| <?php | |
| namespace NoxLogic\DemoBundle\Form\Type; | |
| use Doctrine\ORM\EntityManager; | |
| use NoxLogic\DemoBundle\Entity\Province; | |
| use Symfony\Component\Form\AbstractType; | |
| use Symfony\Component\Form\FormBuilderInterface; | |
| use Symfony\Component\Form\FormEvent; | |
| use Symfony\Component\Form\FormEvents; | |
| use Symfony\Component\Form\FormInterface; | |
| use Symfony\Component\OptionsResolver\OptionsResolverInterface; | |
| class AccountType extends AbstractType { | |
| protected $em; | |
| function __construct(EntityManager $em) | |
| { | |
| $this->em = $em; | |
| } | |
| public function buildForm(FormBuilderInterface $builder, array $options) | |
| { | |
| // Name of the user | |
| $builder->add('name', 'text'); | |
| /* Add additional fields... */ | |
| $builder->add('save', 'submit'); | |
| // Add listeners | |
| $builder->addEventListener(FormEvents::PRE_SET_DATA, array($this, 'onPreSetData')); | |
| $builder->addEventListener(FormEvents::PRE_SUBMIT, array($this, 'onPreSubmit')); | |
| } | |
| protected function addElements(FormInterface $form, Province $province = null) { | |
| // Remove the submit button, we will place this at the end of the form later | |
| $submit = $form->get('save'); | |
| $form->remove('save'); | |
| // Add the province element | |
| $form->add('province', 'entity', array( | |
| 'data' => $province, | |
| 'empty_value' => '-- Choose --', | |
| 'class' => 'NoxLogicDemoBundle:Province', | |
| 'mapped' => false) | |
| ); | |
| // Cities are empty, unless we actually supplied a province | |
| $cities = array(); | |
| if ($province) { | |
| // Fetch the cities from specified province | |
| $repo = $this->em->getRepository('NoxLogicDemoBundle:City'); | |
| $cities = $repo->findByProvince($province, array('name' => 'asc')); | |
| } | |
| // Add the city element | |
| $form->add('city', 'entity', array( | |
| 'empty_value' => '-- Select a province first --', | |
| 'class' => 'NoxLogicDemoBundle:City', | |
| 'choices' => $cities, | |
| )); | |
| // Add submit button again, this time, it's back at the end of the form | |
| $form->add($submit); | |
| } | |
| function onPreSubmit(FormEvent $event) { | |
| $form = $event->getForm(); | |
| $data = $event->getData(); | |
| // Note that the data is not yet hydrated into the entity. | |
| $province = $this->em->getRepository('NoxLogicDemoBundle:Province')->find($data['province']); | |
| $this->addElements($form, $province); | |
| } | |
| function onPreSetData(FormEvent $event) { | |
| $account = $event->getData(); | |
| $form = $event->getForm(); | |
| // We might have an empty account (when we insert a new account, for instance) | |
| $province = $account->getCity() ? $account->getCity()->getProvince() : null; | |
| $this->addElements($form, $province); | |
| } | |
| public function setDefaultOptions(OptionsResolverInterface $resolver) | |
| { | |
| $resolver->setDefaults(array( | |
| 'data_class' => 'NoxLogic\DemoBundle\Entity\Account' | |
| )); | |
| } | |
| public function getName() | |
| { | |
| return "account_type"; | |
| } | |
| } |
| <?php | |
| namespace NoxLogic\DemoBundle\Entity; | |
| use Doctrine\ORM\Mapping as ORM; | |
| /** | |
| * City | |
| * | |
| * @ORM\Table() | |
| * @ORM\Entity() | |
| */ | |
| class City | |
| { | |
| /** | |
| * @var integer | |
| * | |
| * @ORM\Column(name="id", type="integer") | |
| * @ORM\Id | |
| * @ORM\GeneratedValue(strategy="AUTO") | |
| */ | |
| private $id; | |
| /** | |
| * @var string | |
| * | |
| * @ORM\Column(name="name", type="string", length=255) | |
| */ | |
| private $name; | |
| /** | |
| * @ORM\ManyToOne(targetEntity="Province", inversedBy="cities") | |
| */ | |
| protected $province; | |
| /** | |
| * Get id | |
| * | |
| * @return integer | |
| */ | |
| public function getId() | |
| { | |
| return $this->id; | |
| } | |
| /** | |
| * Set name | |
| * | |
| * @param string $name | |
| * @return City | |
| */ | |
| public function setName($name) | |
| { | |
| $this->name = $name; | |
| return $this; | |
| } | |
| /** | |
| * Get name | |
| * | |
| * @return string | |
| */ | |
| public function getName() | |
| { | |
| return $this->name; | |
| } | |
| /** | |
| * Set province | |
| * | |
| * @param \NoxLogic\DemoBundle\Entity\Province $province | |
| * @return City | |
| */ | |
| public function setProvince(\NoxLogic\DemoBundle\Entity\Province $province = null) | |
| { | |
| $this->province = $province; | |
| return $this; | |
| } | |
| /** | |
| * Get province | |
| * | |
| * @return \NoxLogic\DemoBundle\Entity\Province | |
| */ | |
| public function getProvince() | |
| { | |
| return $this->province; | |
| } | |
| function __toString() { | |
| return $this->getName(); | |
| } | |
| } |
| <?php | |
| namespace NoxLogic\DemoBundle\Controller; | |
| use NoxLogic\DemoBundle\Entity\Account; | |
| use NoxLogic\DemoBundle\Form\Type\AccountType; | |
| use Symfony\Bundle\FrameworkBundle\Controller\Controller; | |
| use Symfony\Component\HttpFoundation\JsonResponse; | |
| use Symfony\Component\HttpFoundation\Request; | |
| use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | |
| class DefaultController extends Controller | |
| { | |
| public function ajaxAction(Request $request) { | |
| if (! $request->isXmlHttpRequest()) { | |
| throw new NotFoundHttpException(); | |
| } | |
| // Get the province ID | |
| $id = $request->query->get('province_id'); | |
| $result = array(); | |
| // Return a list of cities, based on the selected province | |
| $repo = $this->getDoctrine()->getManager()->getRepository('NoxLogicDemoBundle:City'); | |
| $cities = $repo->findByProvince($id, array('name' => 'asc')); | |
| foreach ($cities as $city) { | |
| $result[$city->getName()] = $city->getId(); | |
| } | |
| return new JsonResponse($result); | |
| } | |
| public function createAction(Request $request) | |
| { | |
| $account = new Account(); | |
| // You probably want to use a service and inject it automatically. For simplicity, | |
| // I'm just adding it to the constructor. | |
| $form = $this->createForm(new AccountType($this->getDoctrine()->getManager()), $account); | |
| $form->handleRequest($request); | |
| if ($form->isValid()) { | |
| /* Do your stuff here */ | |
| $this->getDoctrine()->getManager()->persist($account); | |
| $this->getDoctrine()->getManager()->flush(); | |
| } | |
| return $this->render('NoxLogicDemoBundle:Default:index.html.twig', array('form' => $form->createView())); | |
| } | |
| } |
| {# Display the form #} | |
| {{ form(form) }} | |
| {# Add ajax thingie that will update the city select box #} | |
| <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script> | |
| <script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script> | |
| <script type="text/javascript"> | |
| $(document).ready(function () { | |
| $('#account_type_province').change(function(){ | |
| var val = $(this).val(); | |
| $.ajax({ | |
| type: "POST", | |
| url: "{{ url('province_ajax_call') }}?province_id=" + val, | |
| success: function(data) { | |
| // Remove current options | |
| $('#account_type_city').html(''); | |
| $.each(data, function(k, v) { | |
| $('#account_type_city').append('<option value="' + v + '">' + k + '</option>'); | |
| }); | |
| } | |
| }); | |
| return false; | |
| }); | |
| }); | |
| </script> |
| <?php | |
| namespace NoxLogic\DemoBundle\Entity; | |
| use Doctrine\ORM\Mapping as ORM; | |
| /** | |
| * Province | |
| * | |
| * @ORM\Table() | |
| * @ORM\Entity() | |
| */ | |
| class Province | |
| { | |
| /** | |
| * @var integer | |
| * | |
| * @ORM\Column(name="id", type="integer") | |
| * @ORM\Id | |
| * @ORM\GeneratedValue(strategy="AUTO") | |
| */ | |
| private $id; | |
| /** | |
| * @var string | |
| * | |
| * @ORM\Column(name="name", type="string", length=255) | |
| */ | |
| private $name; | |
| /** | |
| * @ORM\OneToMany(targetEntity="City", mappedBy="province") | |
| */ | |
| protected $cities; | |
| /** | |
| * Constructor | |
| */ | |
| public function __construct() | |
| { | |
| $this->cities = new \Doctrine\Common\Collections\ArrayCollection(); | |
| } | |
| /** | |
| * Get id | |
| * | |
| * @return integer | |
| */ | |
| public function getId() | |
| { | |
| return $this->id; | |
| } | |
| /** | |
| * Set name | |
| * | |
| * @param string $name | |
| * @return Province | |
| */ | |
| public function setName($name) | |
| { | |
| $this->name = $name; | |
| return $this; | |
| } | |
| /** | |
| * Get name | |
| * | |
| * @return string | |
| */ | |
| public function getName() | |
| { | |
| return $this->name; | |
| } | |
| /** | |
| * Add cities | |
| * | |
| * @param \NoxLogic\DemoBundle\Entity\City $cities | |
| * @return Province | |
| */ | |
| public function addCity(\NoxLogic\DemoBundle\Entity\City $cities) | |
| { | |
| $this->cities[] = $cities; | |
| return $this; | |
| } | |
| /** | |
| * Remove cities | |
| * | |
| * @param \NoxLogic\DemoBundle\Entity\City $cities | |
| */ | |
| public function removeCity(\NoxLogic\DemoBundle\Entity\City $cities) | |
| { | |
| $this->cities->removeElement($cities); | |
| } | |
| /** | |
| * Get cities | |
| * | |
| * @return \Doctrine\Common\Collections\Collection | |
| */ | |
| public function getCities() | |
| { | |
| return $this->cities; | |
| } | |
| function __toString() { | |
| return $this->getName(); | |
| } | |
| } |
Bonjour,
en fait ce formulaire fonctionne a merveille.
mais je trouve un problème lorsque je veux l'imbriquer dans un autre formulaire.
le probleme est dans cette ligne $province = $account->getCity() ? $account->getCity()->getProvince() : null; de accountType.
l'erreur est: Error: Call to a member function getCity() on a non-object
pouvez vous m'aider?
Awesome. Thanks a million.
Hello,
I'm trying to use this solution but since few days I have a persitent error:
Catchable Fatal Error: Argument 1 passed to QuizBundle\Form\AssignType::__construct() must be an instance of Doctrine\ORM\EntityManager, none given, called in D:\qcm\Dev\qcm\vendor\symfony\symfony\src\Symfony\Component\Form\FormRegistry.php on line 85 and defined
And on every forums I went they use the "__construct" function in a controller with:
$this->getDoctrine()->getEntityManager();
So I don't know what to do to fix this error after trying many things.
Can someone help me?
Thank you.
Awasome solution!!!!!!!!!
Thank you for your solution, It's help me a lot!!!!!!!!