-
-
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!!!!!!!!