Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to know which element in body triggered AJAX request in jQuery

Tags:

jquery

I'm working on an app and trying to use the Facebook behavior for an AJAX request. In Facebook you get a nice loading image next to the icon which triggers the AJAX request. Well, it's pretty simple to implement if you have 1-2 elements in the page.

I want to make it generic and would like that whenever any element triggers an AJAX request, I want to show a small GIF next to it. For this, I thought the AjaxSend event of jQuery would be good enough, but alas it doesn't give me a handle of the object which triggered the AJAX call. I would like to know if it is possible via some method of jQuery to know which element triggered the AJAX call and also to get the same handle when the AJAX call is completed.

If you feel my approach to the problem is not correct, I would love to hear your suggestions.

like image 631
Naveen Avatar asked Feb 19 '11 14:02

Naveen


People also ask

Which global event is triggered if an AJAX request?

The ajaxStart and ajaxStop events are events that relate to all Ajax requests together. This event is triggered if an Ajax request is started and no other Ajax requests are currently running.

How do I know if AJAX request is running?

You could use ajaxStart and ajaxStop to keep track of when requests are active. Show activity on this post. Show activity on this post. Checking for null to determine if the request object exists is important, but if it is not null you should really check request.

Which of the following objects send AJAX request?

The keystone of AJAX is the XMLHttpRequest object.

Which object is created in AJAX when an event occurs?

Steps of AJAX Operation A client event occurs. An XMLHttpRequest object is created. The XMLHttpRequest object is configured. The XMLHttpRequest object makes an asynchronous request to the Webserver.


2 Answers

Another generic way that requires least setup is to use activeElement property of the event target:

$(document).ajaxStart(function (e) {
    try {
        var $el = $(e.target.activeElement);
        var isButton = $el.hasClass('btn');

        // just a precautionary check
        if (!isButton) {
            return;
        }

        $el.button('loading'); // or whatever else you want to do

    } catch (ex) {
        console.log(ex);
    }
});

$(document).ajaxStop(function (e) {
    try {
        var $el = $(e.target.activeElement);
        var isButton = $el.hasClass('btn');

        if (!isButton) {
            return;
        }

        $el.button('reset');

    } catch (ex) {
        console.log(ex);
    }
});

The reason this works is because when a button is clicked, it receives focus. And e.target (which is document at this point tells us about the current element in focus via activeElement property.

Note that the try...catch is completely optional. It is usually a good idea to wrap any global handlers in try...catch just to ensure that any exception here doesn't cause any side-effects. The console.log will let you know about the exception, if any, so that you can fix it later.

like image 141
Mrchief Avatar answered Sep 20 '22 14:09

Mrchief


If you want to use the ajax request handlers, an id will need to be assigned (manually or automatically) to the element that triggered the event. You could then send this id as an additional key-value pair in the request (element_id:THEID) and grab it with various substring methods in the ajax request handlers.

Example:

<script type="text/javascript">

    $(document).ready(function(){

        $("input").click(function(){

            var newid = (create a custom id with date and time);

            $(this).attr("id", newid);
            $.post("handler.php", {element_id : $(this).attr("id")});
        });

   }).ajaxSend(function(e, xhr, settings){

        var start_position = settings.data.indexOf("element_id");
        var equalsign_position = settings.data.indexOf("=", start_position);
        var ampersand_position = settings.data.indexOf("&", start_position);

        var element_id;
        if(ampersand_position == -1){
            element_id = settings.data.substr(equalsign_position+1);
        } else {
            element_id = settings.data.substr(equalsign_position+1, ampersand_position-equalsign_position-1);
        }

        $("#"+element_id).after("<div id='div"+element_id+"'><img src='loading_start.png' /></div>");

    }).ajaxComplete(function(e, xhr, settings) {

        var start_position = settings.data.indexOf("element_id");
        var equalsign_position = settings.data.indexOf("=", start_position);
        var ampersand_position = settings.data.indexOf("&", start_position);

        var element_id;
        if(ampersand_position == -1){
            element_id = settings.data.substr(equalsign_position+1);
        } else {
            element_id = settings.data.substr(equalsign_position+1, ampersand_position-equalsign_position-1);
        }

        $("#div"+element_id).remove();


    });

    </script>

    <input type="button" value="Save" />

The alternative is handling the appearing and disappearing of the loading image in each event handler (but I seem to understand you have too many of them?), like this:

<script type="text/javascript">

    $(document).ready(function(){

        $("input").click(function(){


            var element_id = (generate custom id);

            $(this).after("<div id='div"+element_id+"'><img src='loading_start.png' /></div>");

            $.post("handler.php", {var:"hello"}, function(){
                $("#div"+element_id).remove();
            });

        });
    })
</script>
like image 44
flavianatill Avatar answered Sep 17 '22 14:09

flavianatill