7

i have got a little problem here. I have to trigger an event which contains $.post() to load a form and assign it to a DOM. After this is done, i have edit the fields of the form.

I tried:

$.when(function(){
    $('#type_rank_field').trigger('change'); //calls the $.post() to load the form
})
 .done(function(){
    $('#quest_'+questions[i].split('|')[1]).children('option[value="'+questions[i].split('|')[0]+'"]').attr('selected',true);
});

Unfortunately this doesnt work and if i leave it just like that:

$('#type_rank_field').trigger('change');
$('#quest_'+questions[i].split('|')[1]).children('option[value="'+questions[i].split('|')[0]+'"]').attr('selected',true);

The change even looks like this:

        $('#type_rank_field').live('change',function(){
        var id = $(this).children('option:selected').attr('id');
        var id_edited = get_id_from_id(id);
        $.post('ajax/load_questions_of_rank.ajax.php',{id: id_edited},function(data){
            //alert(data);
            $('#rank_fields').html(data);
        });
    });

Then the form editation is executed before the form is properly loaded and attached to DOM. This might be a stupid question for JavaScript guys, but i am mainly a PHP guy so dont be cruel :-)

Thanks

4
  • 1
    Do you really need to trigger the change event? Can you not just refactor the code in your change handler into a separate function that you can just call? Commented Feb 5, 2013 at 16:39
  • Where does get_id_from_id come from? Commented Feb 5, 2013 at 16:39
  • @ROYFinley I was expecting this question. It is such a socifisticated function that nobody will ever try to use it with this name. Commented Feb 5, 2013 at 16:48
  • 1
    Not a solution, but an explanation for what you're seeing now: The callback function you have passed to .done is executed as soon as the function you've passed to .when is executed. That means that the .done callback is executed after the "change" event has been fired, but before it's handlers have been called and so of course before your call to $.post is executed, much less before the post has completed and returned. Commented Feb 5, 2013 at 16:50

4 Answers 4

8

Can separate out your change handler code? Something like this:

$('#type_rank_field').on('change',function(){
    handleChange($(this));
});

function handleChange(elem, callback) {
    var id = elem.children('option:selected').attr('id');
    var id_edited = get_id_from_id(id);
    $.post('ajax/load_questions_of_rank.ajax.php',{id: id_edited},function(data){
        //alert(data);
        $('#rank_fields').html(data);
        if (typeof callback === "function") {
            callback(data);
        }
    });
};

Then instead of triggering the change you can just call handleChange passing a callback to execute when the AJAX call is complete:

handleChange($("#type_rank_field"), function(data) {
    $('#quest_'+questions[i].split('|')[1])
        .children('option[value="'+questions[i].split('|')[0]+'"]')
        .attr('selected',true);
});
Sign up to request clarification or add additional context in comments.

2 Comments

This actually looks like a good idea! I will try it and I will let you know if the problem is solved or not :)
@MattBurland: I only pointed that out as I use this exact pattern sometimes and I've shot myself in the foot before :D. If JS has taught me anything, it's don't rely on type coercion
8

Return the promise object from your event handler:

$(document).on('change','#type_rank_field',function(){
    var id = $(this).children('option:selected').attr('id');
    var id_edited = get_id_from_id(id);
    return $.post('ajax/load_questions_of_rank.ajax.php',{id: id_edited},function(data){
        //alert(data);
        $('#rank_fields').html(data);
    });
});

and then use triggerHandler() instead.

var promise = $('#type_rank_field').triggerHandler('change');
promise && promise.done(function(){
    // do stuff
});

Here's a simple example showing the functionality being used: http://jsfiddle.net/WQPXt/

11 Comments

Wow... is this documented?
Yes, it is documented, the last bullet in first section. api.jquery.com/triggerHandler
Okay Kevin B puts out an answer using the exact depreciated function live() and gets to upvotes. I place an answer that is telling you not to use this function as it could be part of your problem and I get downvoted. How does that work..... -1
@ROY: You are correct, .live should not be used anymore, but not every correct fact answers every question. Your answer does not solve the problem. It's ok as a comment but not as an answer.
This looks ok, but doesnt work :-( I am using 1.8.2. it doesnt even load the form.
|
2

I think we have to add callback after posted

$('#type_rank_field').on('change', function(ev, cb){
    var id = $(this).children('option:selected').attr('id');
    var id_edited = get_id_from_id(id);
    $.post('ajax/load_questions_of_rank.ajax.php',{id: id_edited},function(data){
        //alert(data);
        $('#rank_fields').html(data);
        // add after callback to make sure that html is inserted
        if(typeof cb == "function"){
           cb.apply($(this)) // this apply with the jq object context or another context u want
        }
 });

the trigger change will look like this

$('#type_rank_field').trigger('change', [function(){
  $('#quest_'+questions[i].split('|')[1]).children('option[value="'+questions[i].split('|')[0]+'"]').attr('selected',true);
}]);

Comments

-3

.live has been deprecated in jQuery since v1.7, and has been removed in v1.9.

You should replace it with .on().

.on has 2 signatures for binding elements, whereas .live only had 1.

If the element exists at the time you are binding, you do it like this:

$('.element').on('click', function(){
  .......
});

You can even use the shorthand:

$('.element').click(function(){
  .........
});

If the element does not exist at the time, or new ones will be added (which is what .live was normally used for), you need to use "event delegation":

$(document).on('click', '.element', function(){
  ........
});

NOTE: You want to bind to the closest static element, not always document.

In the meantime, the jQuery Migrate plugin can be used to restore the .live() functionality if you upgrade your jQuery to the newest version.

2 Comments

Thanks for your comment Roy. I will rewrite the .live() function to .on() but i think that doesnt help me with my problem. Is it understandable or should i just describe the problem more deep?
@FelixKling Was try to figure out problem, but user never answered my question form above. Where does get_id_from_id come from? But looks like Matt has it all figured out.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.