Welcome to our second installment of “Advanced jQuery Mobile tutorial”, a new series where we talk about more advanced aspects of jQuery Mobile development. This article will cover everything you need to know about jQuery Mobile client-server communication. Don’t take this too lightly, this is a crucial topic when working on a hybrid jQuery Mobile applications. We will try to cover several different approaches, you only need to decide which one best suits you.
 
 

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.


 

Table of Contents

 
Click here if you want to see other tutorials, this is the 2nd tutorial out of 5 total.

Intro

 
Note: This tutorial is made for jQuery Mobile version 1.4 (possibly 1.5 if jQuery Mobile developers fulfill their promise and postpone depreciation of some methods) and below. I want to cover as many jQuery Mobile users as I can, so I made a decision to use now deprecated (as of jQuery Mobile 1.4) way of page handling. Pagecontainer object introduced in jQuery Mobile 1.4 is still in development, plus it's missing several key features we will use in some future articles. Another reason is that I fear some users won't understand changes made to page handling. If these article series become successful, I will also write examples intended for new page handling.
 
I must confess, first time I worked on a client-server communication using jQuery Mobile and PhoneGap it took me two days to make everything work. Even then, I spent 80% of my time googling how to solve application cross-domain communication problem.
 
Before we continue take a look at this definition:
 
Hybrid apps make it possible to embed HTML5 apps inside a thin native container, combining the best (and worst) elements of native and HTML5 apps.
 
Interesting fact. Currently, 80-90% of jQuery Mobile development is done in the form of hybrid applications. It design and easy syntax make it a perfect vessel for various mobile applications, be it for Android or iOS. So why not just create a plain mobile desktop application and load it directly into PhoneGap, thus skipping additional changes needed to make it fully hybrid available? Short answer would be Apple and it stance against mobile websites acting like mobile apps (find more about it here, look at the reason 5 and 12).
 
We can easily work around previously mentioned reasons, instead of the server-side content generation we need to have everything prepared on the client side. We will contact server side, using AJAX, only to load/refresh our client app with additional content. We will use the same principle native mobile applications are using to communicate with server-side environments.
 

We will cover

 
  • Client / server side communication using JSON
  • Cross-domain client / server side communication using JSONP
 

Example 1 – JSON connection

 
JSON or JavaScript Object Notation is an open standard format that uses human-readable text to transmit data objects consisting of attribute–value pairs. In our case, it is used primarily to transmit data between a server and a client side, as an alternative to XML. Although originally derived from the JavaScript scripting language, JSON is a language-independent data format, and code for parsing and generating JSON data is readily available in a large variety of programming languages.
 
HTML client side –  index.php 
 
<!DOCTYPE html>
<html>
<head>
    <title>jQM Complex Demo</title>
    <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0"/>
	<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.css" /> 
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
	<script src="http://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.js"></script>    
    <script src="js/index.js"></script>
</head>
<body>
    <div data-role="page" id="login" data-theme="a">
        <div data-role="header" data-theme="b">
            <h3>Login Page</h3>
        </div>
 
        <div data-role="content">
            <form id="check-user" class="ui-body ui-body-a ui-corner-all" data-ajax="false">
                <fieldset>
                    <div data-role="fieldcontain">
                        <label for="username">Enter your username:</label>
                        <input type="text" value="" name="username" id="username"/>
                    </div>                                 
                    <div data-role="fieldcontain">                                     
                        <label for="password">Enter your password:</label>
                        <input type="password" value="" name="password" id="password"/>
                    </div>
                    <input type="button" data-theme="b" name="submit" id="submit" value="Submit">
                </fieldset>
            </form>                             
        </div>
 
        <div data-theme="a" data-role="footer" data-position="fixed">
 
        </div>
    </div>
    <div data-role="page" id="second">
        <div data-theme="b" data-role="header">
            <h3>Welcome Page</h3>
        </div>
 
        <div data-role="content">

        </div>
    </div>
</body>
</html>
 
HTML server side –  check.php 
 
<?php
    // We don't need action for this tutorial, but in a complex code you need a way to determine Ajax action nature
    $action = $_POST['action'];
	
    // Decode parameters into readable PHP object
    parse_str($_POST['formData'], $output);
 
    // Get username
    $username = $output['username'];
    // Get password
    $password = $output['password'];
 
    // Let's say everything is in order
    $output = array('status' => true, 'massage' => $username);
    echo json_encode($output);
?>
 
JavaScript:
 
$(document).on('pageinit', '#login', function(){ 
	$(document).on('click', '#submit', function() { // catch the form's submit event
		if($('#username').val().length > 0 && $('#password').val().length > 0){
			// Send data to server through the Ajax call
			// action is functionality we want to call and outputJSON is our data
				$.ajax({url: 'check.php',
					data: {action : 'login', formData : $('#check-user').serialize()},
					type: 'post',                  
					async: 'true',
					dataType: 'json',
					beforeSend: function() {
						// This callback function will trigger before data is sent
						$.mobile.loading('show', {theme:"a", text:"Please wait...", textonly:true, textVisible: true}); // This will show ajax spinner
					},
					complete: function() {
						// This callback function will trigger on data sent/received complete
						$.mobile.loading('hide'); // This will hide ajax spinner
					},
					success: function (result) {
						if(result.status) {
							user.name =  result.massage;
							$.mobile.changePage("#second");                        
						} else {
							alert('Logon unsuccessful!');
						}
					},
					error: function (request,error) {
						// This callback function will trigger on unsuccessful action               
						alert('Network error has occurred please try again!');
					}
				});                  
		} else {
			alert('Please fill all necessary fields!');
		}          
		return false; // cancel original event to prevent form submitting
	});   
});

$(document).on('pagebeforeshow', '#second', function(){ 
    $.mobile.activePage.find('.ui-content').html('Welcome ' + user.name);
});

var user = {
    name : null
}
 
Unfortunately I can’t use jsFiddle to show you a working example, you will need to copy this code and try it by yourself or you can find a working example here.
 
In this example we are using jQuery method $.ajax to communicate with server side. If you carefully take a look, $.ajax function uses JSON as dataType parameter. Parameter url is used to set server side destination. It is worth to know that dataType JSON can only be used inside same domain, for example, you can only access server side code under your own (application) domain. This is good enough if we are working on a mobile site but will ultimately fail if used for hybrid mobile app development. The reason for this is our mobile application doesn’t work as a classic web application, and it will not be part of the same domain. If you need a cross-domain solution take a look at example 2 or 3.
 
The parameter data is used as a data holder object we are going to send to the server side. It is a classic JavaScript object that must hold something, skip it if you are not sending any data. In our case, we are sending two parameters. First one is the parameter action, which will determinate which server side method will trigger to process our data. Next one is formData, which contains our entire form data, thanks to the method serialize().
 
Continue Reading

  • When I tried example 2 with some modification in the code it works in desktop but when I try with the app there is no result. It just stop with “Please wait” message, any suggestion

    /*—————–*/
    $(document).on(‘pageinit’, ‘#home’, function(){
    $(document).on(‘click’, ‘#search-movie’, function(){
    if($(‘#movie-title’).val().length > 0) {
    var url = ‘http://api.themoviedb.org/3/’,
    mode = ‘search/movie?query=’,
    movieName = encodeURI($(‘#movie-title’).val()),
    key = ‘&api_key=470fd2ec8853e25d2f8d86f685d2270e’;
    $.ajax({
    url: url + mode + movieName + key,
    dataType: “jsonp”,
    async: true,
    beforeSend: function() {
    // This callback function will trigger before data is sent
    $.mobile.loading(‘show’, {theme:”a”, text:”Please wait…”, textonly:true, textVisible: true}); // This will show AJAX spinner

    },
    complete: function() {
    // This callback function will trigger on data sent/received complete
    $.mobile.loading(‘hide’); // This will hide AJAX spinner
    },
    success: function (result) {
    ajax.parseJSONP(result);
    },
    error:function(jqXHR, textStatus, errorThrown){
    alert(errorThrown);
    }
    /*error: function (request,error) {
    alert(‘Network error has occurred please try again!’);
    }*/
    });
    } else {
    alert(‘Please enter mobie title!’);
    }
    });
    });

    $(document).on(‘pagebeforeshow’, ‘#headline’, function(){
    $(‘#movie-data’).empty();
    $.each(movieInfo.result, function(i, row) {
    if(row.id == movieInfo.id) {
    //$(‘#movie-data’).append(”);
    $(‘#movie-data’).append(‘Title: ‘+row.original_title+”);
    $(‘#movie-data’).append(‘Release date :’+row.release_date+”);
    $(‘#movie-data’).append(‘Popularity : ‘+row.popularity+”);
    $(‘#movie-data’).append(‘Popularity : ‘+row.vote_average+”); }
    });
    $(‘#movie-data’).listview(‘refresh’);
    });

    $(document).on(‘vclick’, ‘#movie-list li a’, function(){
    movieInfo.id = $(this).attr(‘data-id’);
    $.mobile.changePage( “#headline”, { transition: “slide”, changeHash: false });
    });

    var movieInfo = {
    id : null,
    result : null
    }

    var ajax = {
    parseJSONP:function(result){
    // alert(“success”);
    movieInfo.result = result.results;
    $(‘#movie-list’).empty();
    $.each(result.results, function(i, row) {
    console.log(JSON.stringify(row));
    $(‘#movie-list’).append(‘‘ + row.title + ” + row.vote_average + ‘/10‘);
    });
    $(‘#movie-list’).listview(‘refresh’);
    }
    }

    • Have you enabled internet access for your mobile app?

  • Vida

    Hi Dragan,

    I am working on my college project (web chat application) using jQuery and AJAX, looking for some support from experts like you.

    Please let me know if you can help me to close it out.

    Thanks in advance.

    Regards,
    Vida

    • Hi Vida,

      I don’t have that much time but I can offer you advices so feel free to mail me.

  • PAO

    Hello,

    thanks for this great article !
    In exemple 3 I had to replace $_POST by $_GET in file check.php to make it work.

    I have a question about this third exemple : as we use GET type instead of POST, we cannot send as many value as we want because there is a size limit ? I think it’s not possible to send a picture for exemple ?

    • I would assume you had a cross domain problem that forced you to switch to JSONP (instead of JSON). Most modern browsers wont have problem with URL lenght when working with GET. In case you need to send a large serialized picture you will need to find other cross domain solution (several exist).

  • Ramiro

    Great tutorial! Iam trying to make it work validating user and password from an external data base with jsonp but iam having troubles, ne tip for the mysql condition? Thanx for the time!

    • Best advice would be to use some kind of micro RESTfull framework on your server side.

  • isnt it problematic using GET for passing passwords?

    you wrote that we cannot use JSON for our mobile apps, so we need to use method #3. Because of that we must use GET method, which is considered less secured for passing passwords and such.
    Is it a real problem? if so, how can i use POST?
    Thanks for the teaching article,
    Jonathan

    • Unfortunately I gave a bad impression that example #3 should be used for form authorization.

      Example #3 is made to explain difference between JSON and JSONP calls. JSONP calls are used for cross domain communication, basically any time you need to connect to some
      3rd party API service, like IMDB movie database.

      Also you should never use GET when working with form authorization. I will change my #3 example so no one else can get a bad impression to do that.

  • Rashid

    Hi Dragan,
    Your article is of great help.
    However, I am having a bit of a problem using the same code for my android app. As per example #3, I am using the same server side code as mentioned in your example file HTML server side – check.php. But my ajax call is failing and returns to the error function. But if I replace my domain url with your domain http://example.gajotres.net/json/check2.php the ajax call is a Success. What can be the possible reasons ?

    • 1. Are you testing it inside of your domain or are you doing it outside?
      2. If you are working outside of your domain are you using JSONP?
      3. Are you sure your PHP is accessible outside of your domain?
      4. Are you using Linux/Unix/Windows environment and what browser?
      5. If you are using Windows environment and some kind of LAMP stack (WAMP, XAAMP) have you set it to be accessible outside of your current domain?

  • Chener

    Phonegap App built with Phonegap Build now supports cross-domain requests, however Phonegap Developer App does not 🙁

    • When you run your application on a smartphone it will not suffer from ross-domain requests problem. đ

      If you want to do it also in a desktop browser you will need to slightly change your server side code, replacing JSON with JSONP which is cross-domain compatible. Downside of this solution, you can only use GET, POST is out of the question.

  • Cédric

    Hi. When I put the PHP file on my servor, I have a “Welcome null” on the second page and not when I’m using your url in the index.js. I don’t understand because my url is reachable by Ajax ( [HTTP/1.1 200 OK 256 ms]). Have you got an idea ? I’m trying to see in the apache .htaccess.
    Thanks