问题
I am trying to get this form to dynamically populate the select box with the related Posts once the Owner has been selected in the previous dropdown. My entities are all ok however I can't see what I'm missing in the below files that is stopping the Ajax requests from firing:
My Controller
/**
* @Route("/newUser", name="new_User")
*/
public function updatePostsAction(Request $request)
{
$User = new User();
$form = $this->createForm(new UserType(), $User);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($owner);
$em->persist($post);
$em->persist($user);
$em->persist($location);
$em->flush();
return $this->redirectToRoute('homepage');
}
return $this->render('AppBundle:Default:adminupdate.post.html.twig', array(
'form' => $form->createView(),
));
}
/**
* @Route("/newUserAjax", name="new_user_ajax")
*/
public function newUserAjaxAction(Request $request)
{
return new JsonResponse($posts);
}
My User FormType
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('Owners','entity',array(
'class'=>'AppBundle:Owner',
'placeholder' => '-- Choose --',
'choice_label'=>'OwnerDesc',
'query_builder'=>function(EntityRepository $er) {
return $er->createQueryBuilder('d')
->orderBy('d.OwnerDesc','ASC');
}))
->add('firstname')
->add('surname')
->add('DOB');
// Add listeners for Post field
$builder->addEventListener(FormEvents::PRE_SET_DATA, array($this, 'onPreSetData'));
$builder->addEventListener(FormEvents::PRE_SUBMIT, array($this, 'onPreSubmit'));
}
protected function addElements(FormInterface $form, $Owner = null)
{
if($Owner){
$form->add('Posts','entity',array(
'class'=>'AppBundle:Post',
'placeholder' => '-- Choose --',
'choice_label'=>'PostDesc',
'query_builder'=>function(EntityRepository $er, $Owner) {
return $er->createQueryBuilder('e')
->join('e.Owner_id', 'd')
->where('d.Ownerid = :id')
->setParameter('id', $Owner->getOwnerid() )
->orderBy('e.Postdate','ASC');
}));
}
else{
$form->add('Posts','choice',array(
'choice_label'=>'dummytext',
'placeholder' => '-- Choose --',
'choices' => array())
);
}
}
public function onPreSubmit(FormEvent $event)
{
$form = $event->getForm();
$data = $event->getData();
$this->addElements($form, $data->getOwners());
}
public function onPreSetData(FormEvent $event)
{
/** @var User User */
$User = $event->getData();
$form = $event->getForm();
$this->addElements($form, $User->getOwners());
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\User',
));
}
public function getName()
{
return 'User';
}
}
My Twig template:
{{ form_start(form) }}
{{ form_row(
form.Owners,
{
'attr':
{
'data-Owner-id': "form.Owner.vars.Owner_id",
'class': "change-posts-per-owner",
}
}
) }}
{{ form_row(form.Posts, {'label' : 'Select Post of Owner'} ) }}
{{ form_row(form.firstname, {'label' : 'Firstname(s)'} ) }}
{{ form_row(form.surname, {'label' : 'Surname'} ) }}
{{ form_row(form.DOB, {'label' : 'Date of Birth'} ) }}
<input type="submit" value="Add" />
{{ form_end(form) }}
My ajax script:
$(document).on('change', 'change-posts-per-owner', function(){
var Ownerid = $(this).data("Owner-id");
$.ajax({
url: "{{ path('new_User_ajax') }}",
type: "GET",
data: 'Ownerid='+Ownerid,
dataType: 'JSON',
error: function (data) {
alert("An error ocurred." + data);
},
success:function(data) {
$.each(data, function(k, v) {
$(child).append('<option value="' + v[itemKey] + '">' + v[itemLabel] + '</option>');
});
}
})
});
UPDATE: including my entities
User entity....
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Users
*
* @ORM\Table(name="Users")
* @ORM\Entity
*/
class User
{
/************************************************************
* Variables
************************************************************/
/**
* @var integer
*
* @ORM\Column(name="Userid", type="bigint")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $Userid;
/**
* @var string
*
* @ORM\Column(name="firstname", type="text", length=65535, nullable=true)
*/
private $firstname;
/**
* @var string
*
* @ORM\Column(name="surname", type="text", length=65535, nullable=true)
*/
private $surname;
/**
* @var \DateTime
*
* @ORM\Column(name="dob", type="date", nullable=true)
*/
private $DOB;
/**
* @var string
*
* @ORM\Column(name="Posts", type="text", length=65535, nullable=true)
*/
private $Posts;
/**
* @var string
*
* @ORM\Column(name="Owners", type="text", length=65535, nullable=true)
*/
private $Owners;
/************************************************************
* Getters/setters
************************************************************/
/************************************************************
* Get Userid
* @return integer
*/
public function getUserid()
{
return $this->Userid;
}
/************************************************************
* Get Posts
* @return string
*/
public function getPosts()
{
return $this->Posts;
}
/**
* Set Posts
* @param string $Posts
* @return User
*/
public function setPosts($Posts)
{
$this->Posts = $Posts;
return $this ;
}
/************************************************************
* Get Owners
* @return string
*/
public function getOwners()
{
return $this->Owners;
}
/**
* Set Owners
* @param string $Owners
* @return User
*/
public function setOwners($Owners)
{
$this->Posts = $Owners;
return $this ;
}
/************************************************************
* Get firstname
*
* @return string
*/
public function getFirstname()
{
return $this->firstname;
}
/**
* Set firstname
*
* @param string $firstname
*
* @return User
*/
public function setFirstname($firstname)
{
$this->firstname = $firstname;
return $this;
}
/************************************************************
* Get nameSurname
*
* @return string
*/
public function getNameSurname()
{
return $this->nameSurname;
}
/**
* Set nameSurname
*
* @param string $nameSurname
*
* @return User
*/
public function setNameSurname($nameSurname)
{
$this->nameSurname = $nameSurname;
return $this;
}
/************************************************************
* Set DOB
*
* @param string $DOB
*
* @return User
*/
public function setDOB($DOB)
{
$this->DOB = $DOB;
return $this;
}
/**
* Get DOB
*
* @return string
*/
public function getDOB()
{
return $this->DOB;
}
}
Post entity....
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Posts
*
* @ORM\Table(name="Posts", indexes={@ORM\Index(name="fk_Posts_Owners_idx", columns={"Owner_id"}),
* @ORM\Index(name="fk_Posts_Users_idx", columns={"User_id"})})
* @ORM\Entity
*/
class Post
{
/************************************************************
* Variables
************************************************************/
/**
* @var integer
*
* @ORM\Column(name="Postid", type="bigint")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $Postid;
/**
* @var \AppBundle\Entity\Owner
*
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Owner")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="Owner_id", referencedColumnName="Ownerid")
* })
*/
private $Owner_id;
/**
* @var string
*
* @ORM\Column(name="Post_desc", type="text", length=65535, nullable=false)
*/
private $PostDesc;
/**
* @var \DateTime
*
* @ORM\Column(name="Postdate", type="date", nullable=true)
*/
private $Postdate;
/**
* @var \AppBundle\Entity\User
*
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="User_id", referencedColumnName="Userid")
* })
*/
private $User;
/************************************************************
* Getters/setters
************************************************************/
/************************************************************
* Get Postid
*
* @return integer
*/
public function getPostid()
{
return $this->Postid;
}
/**
* Set Postid
*
* @param integer $Postid
*
* @return Post
*/
public function setPostid($Postid)
{
$this->Postid = $Postid;
return $this;
}
/************************************************************
* Get Owner
*
* @return \AppBundle\Entity\Owner
*/
public function getOwner()
{
return $this->Owner_id;
}
/**
* Set Owner
*
* @param \AppBundle\Entity\Owner $Owner
*
* @return Post
*/
public function setOwner(\AppBundle\Entity\Owner $Owner)
{
$this->Owner_id = $Owner;
return $this;
}
/************************************************************
* Get PostDesc
*
* @return string
*/
public function getPostDesc()
{
return $this->PostDesc;
}
/**
* Set PostDesc
*
* @param string $PostDesc
*
* @return Post
*/
public function setPostDesc($PostDesc)
{
$this->PostDesc = $PostDesc;
return $this;
}
/************************************************************
* Get Postdate
*
* @return \DateTime
*/
public function getPostdate()
{
return $this->Postdate;
}
/**
* Set Postdate
*
* @param \DateTime $Postdate
*
* @return Post
*/
public function setPostdate($Postdate)
{
$this->Postdate = $Postdate;
return $this;
}
/************************************************************
* Get User
*
* @return \AppBundle\Entity\User
*/
public function getUser()
{
return $this->User;
}
/**
* Set User
*
* @param \AppBundle\Entity\User $User
*
* @return Post
*/
public function setUser(\AppBundle\Entity\User $User = null)
{
$this->User = $User;
return $this;
}
}
Owner entity...
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Owners
*
* @ORM\Table(name="Owners", indexes={@ORM\Index(name="fk_Owners_communities_idx", columns={"community_id"})})
* @ORM\Entity
*/
class Owner
{
/************************************************************
* Variables
************************************************************/
/**
* @var integer
*
* @ORM\Column(name="Ownerid", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $Ownerid;
/**
* @var \AppBundle\Entity\community
*
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\community")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="community_id", referencedColumnName="communityid")
* })
*/
private $community;
/**
* @var string
*
* @ORM\Column(name="Owner_desc", type="text", length=65535, nullable=false)
*/
private $OwnerDesc;
/**
* @var string
*
* @ORM\Column(name="author_firstname", type="text", length=65535, nullable=true)
*/
private $authorFirstname;
/**
* @var string
*
* @ORM\Column(name="author_surname", type="text", length=65535, nullable=true)
*/
private $authorSurname;
/************************************************************
* Getters/setters
************************************************************/
/************************************************************
* Get Ownerid
*
* @return integer
*/
public function getOwnerid()
{
return $this->Ownerid;
}
/************************************************************
* Get OwnerDesc
*
* @return string
*/
public function getOwnerDesc()
{
return $this->OwnerDesc;
}
/**
* set OwnerDesc
*
* @param string $OwnerDesc
*
* @return Owner
*/
public function setOwnerDesc($OwnerDesc)
{
$this->OwnerDesc = $OwnerDesc;
return $this;
}
/************************************************************
* Get authorFirstname
*
* @return string
*/
public function getAuthorFirstname()
{
return $this->authorFirstname;
}
/**
* set authorFirstname
*
* @param string $authorFirstname
*
* @return Owner
*/
public function setAuthorFirstname($authorFirstname)
{
$this->authorFirstname = $authorFirstname;
return $this;
}
/************************************************************
* Get authorSurname
*
* @return string
*/
public function getAuthorSurname()
{
return $this->authorSurname;
}
/**
* set authorSurname
*
* @param string $authorSurname
*
* @return Owner
*/
public function setAuthorSurname($authorSurname)
{
$this->authorSurname = $authorSurname;
return $this;
}
/************************************************************
* Get community
*
* @return \AppBundle\Entity\community
*/
public function getcommunity()
{
return $this->community;
}
/**
* set community
*
* @param \AppBundle\Entity\community $community
*
* @return Owner
*/
public function communitiecommunity(\AppBundle\Entity\community $community = null)
{
$this->community = $community;
return $this;
}
}
回答1:
Ok ! First of all, there can be several owners ? Several posts for one User ?
Owners
and Posts
are strange here. Could you please add your AppBundle\Entity\User
entity with mapping (annotation, yml, xml). I think there is finally a mistake in UserType..
In you Ajax script, Ownerid
is well get ?
Test it by doing console.log(Ownerid)
just after it has been defined.
In order to see Ajax calls and returns, press F12 and go to console panel and after, change owner in your select in order to trigger Ajax call.
Also, 'data-Owner-id': "form.Owner.vars.Owner_id",
is probably wrong because your relation is named Owners
instead of Owner
.
Anyway, I finally think that this data
attribute is unecessary and you can remove it and in your ajax call get OwnerID
just by var Ownerid = $(this).val();
. It should be id
of selected Owner
.
Add an unique id for your child <select/>
(for posts) for example : posts-select
.
In your method called by Ajax (in your controller) you forgot parameter :
/**
* @Route("/newUserAjax/{Ownerid}", name="new_user_ajax", options={"expose"=true})
* @ParamConverter("owner", class="AppBundle:Owner", options={"id" = "Ownerid"})
*/
public function newUserAjaxAction(Owner $owner)
{
$posts = $owner->getPosts(); // I assume that in you Owner entity there is an attribute posts (a OneToMany relation)
return new JsonResponse($posts);
}
In your success:function(data)
you can do :
success:function(data) {
var child = $(document).find('#posts-select');
$.each(data, function(k, v) {
$(child).append('<option value="' + v[itemId] + '">' + v[itemName] + '</option>');
});
}
Where id
and name
are attributes from Post
entity.
Before adding <option
elements, be sure to remove those currently displayed by something like : $(child).find('option:not(:first-child)').remove();
(first-child being placeholder).
UDPATE :
You should install FOSJSRouting Bundle in order to use expose=true
(in your routing) an Routing.generate()
(in your ajax script)
$.ajax({
url: Routing.generate('new_User_ajax', {id: Ownerid }),
来源:https://stackoverflow.com/questions/34030619/why-isnt-this-ajax-call-capturing-the-onchange-event-in-symfony