1

I am binding different loading messages for two different events.

Here are the functions that I'm using to bind the behaviour before AJAX calls. I am calling each function before each matching Ajax submission so that it will show the correct loading messages for each one:

function BindPersonalityLoader()
{

    // Bind the loader to personality
    $('document').bind("ajaxStart", function() {
        // Show the loader
        $('img#personality_loader').show();
    });

    // Bind the loader to personality
    $('document').bind("ajaxStop", function() {
        // Show the loader
        $('img#personality_loader').hide();
    });
}

function BindLoadEditPersonalityLoader()
{

    // Bind the loader for editing a personality
    $('document').bind("ajaxStart", function() {

        // Hide the edit form
        $('div#quiz_maker_add_personality_wrapper').hide();

        // Show the loader
        $('div#quiz_maker_edit_personality_loader').show();
    });

    // Bind the loader for editing a personality
    $('document').bind("ajaxStop", function() {

        // Hide the loader
        $('div#quiz_maker_edit_personality_loader').hide();
    });
}

As soon as I have called BindLoadEditPersonalityLoader(), this becomes permanent for some reason, even if I then call BindPersonalityLoader() within my code, I expect the other behaviour.

For some reason why I call the code, it is not overriding the "bind".

For example if I run the following code, the behaviour of BindLoadEditPersonalityLoader() remains throughout, because it was called first:

// Bind the loaders once
BindLoadEditPersonalityLoader();

// Bind the loaders to different behaviour
BindPersonalityLoader();

I have included the two alert() messages so that I can see when they have been called.

I have tried calling unbind("ajaxStart ajaxStop"); but this didn't work either.

This is how I am calling the binds within my two different events:

    // Add a new personality to the quiz
$('form#personality_editor').submit(function(e) {

    e.preventDefault();

    // Bind the loader to personality loader
    BindPersonalityLoader();

            // AJAX Call here

    });

    // Edit a personality already existing within the quiz
$('a.personality_edit').live('click', function(e) {

    e.preventDefault();

    // Bind loader for editing personality
    BindLoadEditPersonalityLoader();

            // Ajax call here
    });
Luke
  • 22,826
  • 31
  • 110
  • 193

2 Answers2

1

ajaxStop and ajaxStart are global events, the event is triggered on all elements any time an ajax request is started when there are no other pending ajax requests, and each time an ajax request is ended when there are no other pending ajax requests.

I see no reason to have more than one loading box. Have you considered only having one loading box, but having a way to simply change what was displayed in it?

$("#loader").ajaxStart(function(){
    $(this).show();
}).ajaxStop(function(){
    $(this).fadeOut();
});
// ... later on ...
$("#loader span.infotext").text("Loading User Profile, please wait...");
$.ajax({ ... });
Kevin B
  • 94,570
  • 16
  • 163
  • 180
0

The bind isn't being "overwritten" because you're binding the events to different objects.

$('img#personality_loader').bind("ajaxStart", function() {...});
$('div#quiz_maker_edit_personality_loader').bind("ajaxStart", function() {...});

Try binding/unbinding on $(document) (without 's)

Luke
  • 22,826
  • 31
  • 110
  • 193
pdoherty926
  • 9,895
  • 4
  • 37
  • 68
  • I've changed it to `document` and my loading messages don't appear. Why does a bind have to be bound to an element at all? – Luke Sep 12 '12 at 13:01
  • Actually no, it's still not working when binding them all to document :( – Luke Sep 12 '12 at 13:07
  • [I suppose you could try binding the events to `$({})`.](http://stackoverflow.com/questions/5411228/jquery-custom-events-on-non-dom-objects#5411253) – pdoherty926 Sep 12 '12 at 13:07
  • Thanks for your suggestion but I don't understand? How do you mean, bind to `$({})`. The link doesn't show what you mean either. – Luke Sep 12 '12 at 13:14
  • I was suggesting binding the events on a non-DOM object, which is a bit clunky and confusing. That idea was covered in the linked post and is also discussed [here](https://groups.google.com/forum/?fromgroups=#!topic/jquery-en/yiQHKKlCULQ). However, upon further consideration, why not just bind these events once and then have some conditional logic inside the callbacks that figures out what to do? – pdoherty926 Sep 12 '12 at 13:25
  • If you could give me a code sample to suggest how make use of `ajaxStart` and `ajaxStop` events for two different cases, I'd be most grateful – Luke Sep 12 '12 at 13:31
  • [This](http://jsfiddle.net/hnSfY/) is a naive implementation of my second suggestion (only binding the events once). – pdoherty926 Sep 12 '12 at 13:45
  • Great, I get that. When you say naive, is this a bad way to do it? – Luke Sep 12 '12 at 14:10
  • No - not necessarily. I'm not *crazy* about the use of a global variable to handle the control flow, but if you wrap your code in an [IIFE](http://benalman.com/news/2010/11/immediately-invoked-function-expression/) and make sure to use the `var` keyword when defining it, it's not *so* bad. – pdoherty926 Sep 12 '12 at 14:20
  • I don't understand why jQuery have created a framework which assumes that you would only want one loader per page. How many applications have multiple loaders on one page. What is the correct way of doing it? – Luke Sep 12 '12 at 14:24