The loader widget handles the task of displaying the loading dialog when jQuery Mobile pulls in content via Ajax. It can also be displayed manually for custom loading actions but, what can we do if we want to show it when we initiate $.ajax call? Or how can we do it during the page transition process.
 
 

Note: If this tutorial was helpful, need further clarification, something is not working or do you have a request for another Ionic post? Furthermore, if you don't like something about this blog, if something is bugging you, don't like how I'm doing stuff here, again leave me a comment below. I'm here to help you, I expect the same from you. Feel free to comment below, subscribe to my blog, mail me to dragan.gaic@gmail.com, or follow and mention me on twitter (@gajotres). Thanks and have a nice day!

PS. If you want my help, if possible (even if it takes you some time to do that), create a working example I can play with. Use Plunker for AngularJS based questions or jsFiddle for jQuery/jQuery Mobile based questions.


 
Before we start we need to discuss one unlikely jQuery Mobile feature, basically you can’t manually trigger jQuery Mobile Ajax loader on web-kit browsers, at least not that easy. For some reason, you can only trigger it after a small delay, usually inside a setTimeout function. Because of this my examples will use a custom cross-platform loading function:
 
function loading(showOrHide) {
    setTimeout(function(){
        $.mobile.loading(showOrHide);
    }, 1); 
}
 
Here’s a difference:
 
 
Update: If you can't see a working example that probably means plnkr.co is down ... again. Also, funny thing, jQuery Mobile Ajax loaders will work correctly on web-kit browsers when viewed inside an iFrame. At the same time, animation will work purely so I advise you to try these examples locally.
 
Ajax loader is not working in the first example (web-kit browsers only), at a same time it works in a second example.
 

Example 1

In this example, I will show you how to enable Ajax loader globally, it will automatically work each time you initiate an $.ajax call.
 
$(document).on({
    ajaxSend: function () { loading('show'); },
    ajaxStart: function () { loading('show'); },
    ajaxStop: function () { loading('hide'); },
    ajaxError: function () { loading('hide'); }
});

function loading(showOrHide) {
    setTimeout(function(){
        $.mobile.loading(showOrHide);
    }, 1); 
}
 

Example 2

The second example will show you how to do this during the page transition period, while a page1 is transitioning to a page2. For this occasion, we will need to customize function loading.
 
<!DOCTYPE html>
<html>
<head>
    <title>jQM Complex Demo</title>
    <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0; user-scalable=no; target-densityDpi=device-dpi"/>
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.min.css" />
    <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
    <script src="http://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.min.js"></script>    
    <script src="script.js"></script>       
</head>
<body>
    <div data-role="page" id="index">
        <div data-theme="a" data-role="header">
            <h3>
                First Page
            </h3>
            <a href="#second" class="ui-btn-right">Next</a>
        </div>
        <div data-role="content">
        </div>
        <div data-theme="a" data-role="footer" data-position="fixed">
        </div>
    </div>    
    <div data-role="page" id="second">
        <div data-theme="a" data-role="header">
            <h3>
                First Page
            </h3>
            <a href="#index" class="ui-btn-left">Back</a>
        </div>
        <div data-role="content">
        </div>
        <div data-theme="a" data-role="footer" data-position="fixed">
        </div>
    </div>     
</body>
</html>   
 
$(document).on('pagebeforecreate', '[data-role="page"]', function() {
  loading('show', 1);
});

$(document).on('pageshow', '[data-role="page"]', function() {
  loading('hide', 1000);
});

function loading(showOrHide, delay) {
  setTimeout(function() {
    $.mobile.loading(showOrHide);
  }, delay);
}
 
If you want to see how this example works just change the page in below example:
 
 

Who Am I?

Between working as a senior Java developer in one of the largest insurance companies in the world and traveling, in my free time, I work as a professional mobile development adviser. I'm also a major jQuery Mobile supporter back at StackOverflow and a forum moderator at the official Ionic Framework forum.

Blogs worth reading

If you're here looking for information related to the Ionic Framework, you will also like these blogs:






  • Bhumi

    nice post. very helpful to me.

  • First, brilliant Blog, helped a lot during my mobile coding life so far, THANK YOU!

    For Example 1, it should be “loading(‘show’);” instead of “loading(show);”

    For Example 2, If I use single page structure, do I still need this setting ?

    Also, I think setTimeout(fn(), 0) is enough.

  • Ibrahim Samad

    That was an awesome post.
    Please I have a jquery mobile app that reads rss feeds. But the problem is that before the feeds are shown, an empty list elements are displayed for 3sec before the feeds are marked up. I want to rather see an ajax loader before the feeds.
    Please any help

    • Are you doing this during page transition or?

      • Ibrahim Samad

        Thanks for your reply.
        No pls. Just when the page loads for the first time. I retrieve the feeds online.

        I called the getFeeds(url); function in $(function(){

        //like

        getFeeds(url);

        });

        This is the js fiddle: http://jsfiddle.net/naatogmajsfiddle/729sgq2f/1/

        • 1. First update your jQuery Mobile 🙂 you’re using almost 5 year old version, plus jQuery Mobile js file included with jsFiddle is not matching jQuery Mobile CSS file

          2. There’s a simple solution for your list element problem. Add li elements during listEntries function call, not before.

          Here’s what’s happening in your case:

          a) Listview is filled with 20 li elements
          b) Application is creating a REST call to retrieve blog posts (this step is creating a several sec delay)
          c) Listview elements are filled with retrieved data

          Your problem is delay made by point b. You can skip it of you combine point a and c together, after a successful REST call.

          • Ibrahim Samad

            Thanks very much for your quick reply….I have updated the jquery, jqm, and css files to the latest versions. When I added the li elements during the listEntries function call, as you stated in point 2 above, which was called inside the getOnlineContent function in a query string, the result is that the entries are no more listed, only the content is shown with unstyled css. I tried calling it also in where the getOnlineContent was called but after it, and it was the same results. ie no entries and unstyled content.

          • Then you have an error somewhere. Have you checked DOM content, is newly added content there?

          • Ibrahim Samad

            Yh sorry for that…Now it displayed the list, but the jquery mobile style that applies to listview content doesn’t work anymore. The list just appeared as default bullet list… and the links inside the li are also unstyled. I checked that jquerymobile.css was loaded correctly. I don’t know what went wrong.

            Thanks…

          • Ibrahim Samad

            My problem is strange in the sense that, when I start to search in the list view using the filter, the list is rendered normally with the styles. But when the page loads, the styles doesn’t apply straight away. That is after I made those changes…

          • I would advise you to sit and learn jQuery Mobile a bit first though I’ll tell you what to do.

            First read these articles:

            http://www.gajotres.net/how-jquery-mobile-page-handling-affects-javascript-executions/
            http://www.gajotres.net/document-onpageinit-vs-document-ready/
            http://www.gajotres.net/jquery-mobile-and-how-to-enhance-the-markup-of-dynamically-added-content/

            Then decide what to do:

            1. Use your JavaScript code during pagecreate event (read second article to learn about jQuery Mobile page events)
            2. Manually trigger markup enhancement of listview component (its described in the third link)

          • Ibrahim Samad

            I appreciate your effort and time. Thanks for the advice.