Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
260 views
in Technique[技术] by (71.8m points)

jquery - Why isn't this AJAX call capturing the onChange event in Symfony?

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' => 'AppBundleEntityUser',
    ));
    }

    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 AppBundleEntity;
use DoctrineORMMapping as ORM;
/**
 * Users
 *
 * @ORMTable(name="Users")
 * @ORMEntity
 */
class User
{
    /************************************************************
     * Variables
     ************************************************************/

    /**
     * @var integer
     *
     * @ORMColumn(name="Userid", type="bigint")
     * @ORMId
     * @ORMGeneratedValue(strategy="AUTO")
     */
    private $Userid;

    /**
     * @var string
     *
     * @ORMColumn(name="firstname", type="text", length=65535, nullable=true)
     */
    private $firstname;

    /**
     * @var string
     *
     * @ORMColumn(name="surname", type="text", length=65535, nullable=true)
     */
    private $surname;

    /**
     * @var DateTime
     *
     * @ORMColumn(name="dob", type="date", nullable=true)
     */
    private $DOB;

    /**
     * @var string
     *
     * @ORMColumn(name="Posts", type="text", length=65535, nullable=true)
     */
    private $Posts;

    /**
     * @var string
     *
     * @ORMColumn(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 AppBundleEntity;
use DoctrineORMMapping as ORM;
/**
 * Posts
 *
 * @ORMTable(name="Posts", indexes={@ORMIndex(name="fk_Posts_Owners_idx", columns={"Owner_id"}),
 *                                     @ORMIndex(name="fk_Posts_Users_idx", columns={"User_id"})})
 * @ORMEntity
 */
class Post
{
    /************************************************************
     * Variables
     ************************************************************/
    /**
     * @var integer
     *
     * @ORMColumn(name="Postid", type="bigint")
     * @ORMId
     * @ORMGeneratedValue(strategy="AUTO")
     */
    private $Postid;

    /**
     * @var AppBundleEntityOwner
     *
     * @ORMManyToOne(targetEntity="AppBundleEntityOwner")
     * @ORMJoinColumns({
     *   @ORMJoinColumn(name="Owner_id", referencedColumnName="Ownerid")
     * })
     */
    private $Owner_id;

    /**
     * @var string
     *
     * @ORMColumn(name="Post_desc", type="text", length=65535, nullable=false)
     */
    private $PostDesc;

    /**
     * @var DateTime
     *
     * @ORMColumn(name="Postdate", type="date", nullable=true)
     */
    private $Postdate;

    /**
     * @var AppBundleEntityUser
     *
     * @ORMManyToOne(targetEntity="AppBundleEntityUser")
     * @ORMJoinColumns({
     *   @ORMJoinColumn(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 AppBundleEntityOwner
     */
    public function getOwner()
    {
        return $this->Owner_id;
    }

    /**
     * Set Owner
     *
     * @param AppBundleEntityOwner $Owner
     *
     * @return Post
     */
    public function setOwner(AppBundleEntityOwner $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()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 AppBundleEntityUser 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 }),

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...