Lets build our jQuery Mobile application

 
Our application will use external JSON source, specifically themoviedb database. And to make it more interesting, iScroll will be used for more native-like scrolling.
 

HTML

 
<div data-role='page' id='home'>
    <div data-theme='a' data-role='header'>
        <h3>
            Movie List
        </h3>
    </div>        
    <div data-role='content'>
        <div class='example-wrapper' data-iscroll>
            <ul data-role='listview'  id='movie-list' data-theme='a'>
                
            </ul>
        </div>
    </div>
    <div data-theme='a' data-role='footer'>
        <h1>Copyright 2013</h1>
    </div>              
</div>
<div data-role='page' id='headline'>
    <div data-theme='a' data-role='header'>
        <a href='#home' class='ui-btn-left' data-transition='slide' data-direction='reverse'>Back</a>                        
        <h3>
            Movie Info
        </h3>
    </div>        
    <div data-role='content'>
        <ul data-role='listview'  id='movie-data' data-theme='a'>
            
        </ul>
    </div>
</div>    
 

Javascript

 
$(document).on('pageinit', '#home', function(){      
    var url = 'http://api.themoviedb.org/3/',
        mode = 'search/movie?query=',
        movieName = '&amp;query='+encodeURI('Batman'),        
        key = '&amp;api_key=470fd2ec8853e25d2f8d86f685d2270e';        
    
    $.ajax({
        url: url + mode + key + movieName ,
        dataType: 'jsonp',
        async: true,
        success: function (result) {
            ajax.parseJSONP(result);
        },
        error: function (request,error) {
            alert('Network error has occurred please try again!');
        }
    });         
});

$(document).on('pagebeforeshow', '#headline', function(){      
    $('#movie-data').empty();
    $.each(movieInfo.result, function(i, row) {
        if(row.id == movieInfo.id) {
            $('#movie-data').append('<li><img src='http://d3gtl9l2a4fn1j.cloudfront.net/t/p/w185'+row.poster_path+''></li>');
            $('#movie-data').append('<li>Title: '+row.original_title+'</li>');
            $('#movie-data').append('<li>Release date'+row.release_date+'</li>');
            $('#movie-data').append('<li>Popularity : '+row.popularity+'</li>');   
            $('#movie-data').append('<li>Popularity : '+row.vote_average+'</li>');             
            $('#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){  
        movieInfo.result = result.results;
        $.each(result.results, function(i, row) {
            console.log(JSON.stringify(row));
            $('#movie-list').append('<li><a href='' data-id='' + row.id + ''><img src='http://d3gtl9l2a4fn1j.cloudfront.net/t/p/w185'+row.poster_path+''/><h3>' + row.title + '</h3><p>' + row.vote_average + '/10</p></a></li>');
        });
        $('#movie-list').listview('refresh');
    }
}   
 

CSS

 
.ui-content {
    padding: 0 !important;
}
 
.ui-listview {
    margin: 0 !important;
}
 
.example-wrapper, .example-wrapper div.iscroll-scroller {
    width: 100% !important;
}
 
Working Example
 
 

Lets mix everything up

 
At this point, we have a working Cordova project and working jQuery Mobile example.
 
Let’s create a index.html file from our jsFiddle example, it should look like this:
 
<!DOCTYPE html>
<html>
    <head>
        <title>jQM Complex Demo</title>
        <meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
		<meta name='viewport' content='width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no'/>
        <link rel='stylesheet' href='http://code.jquery.com/mobile/1.4.0-beta.1/jquery.mobile-1.4.0-beta.1.min.css'/>
        <link rel='stylesheet' href='http://example.gajotres.net/iscrollview/jquery.mobile.iscrollview.css'/>
		<link rel='stylesheet' href='http://example.gajotres.net/iscrollview/jquery.mobile.iscrollview-pull.css'/>
		<style>
			.ui-content {
				padding: 0 !important;
			}
			 
			.ui-listview {
				margin: 0 !important;
			}
			 
			.example-wrapper, .example-wrapper div.iscroll-scroller {
				width: 100% !important;
			}
		</style>
        <script src='http://code.jquery.com/jquery-1.10.1.min.js'></script>
        <script src='http://code.jquery.com/mobile/1.4.0-beta.1/jquery.mobile-1.4.0-beta.1.min.js'></script>
        <script src='http://example.gajotres.net/iscrollview/iscroll.js'></script>
		<script src='http://example.gajotres.net/iscrollview/jquery.mobile.iscrollview.js'></script>
		<script>
			$(document).on('pageinit', '#home', function(){      
				var url = 'http://api.themoviedb.org/3/',
					mode = 'search/movie?query=',
					movieName = '&amp;query='+encodeURI('Batman'),        
					key = '&amp;api_key=5fbddf6b517048e25bc3ac1bbeafb919';        
				
				$.ajax({
					url: url + mode + key + movieName ,
					dataType: 'jsonp',
					async: true,
					success: function (result) {
						ajax.parseJSONP(result);
					},
					error: function (request,error) {
						alert('Network error has occurred please try again!');
					}
				});         
			});

			$(document).on('pagebeforeshow', '#headline', function(){      
				$('#movie-data').empty();
				$.each(movieInfo.result, function(i, row) {
					if(row.id == movieInfo.id) {
						$('#movie-data').append('<li><img src='http://d3gtl9l2a4fn1j.cloudfront.net/t/p/w185'+row.poster_path+''></li>');
						$('#movie-data').append('<li>Title: '+row.original_title+'</li>');
						$('#movie-data').append('<li>Release date'+row.release_date+'</li>');
						$('#movie-data').append('<li>Popularity : '+row.popularity+'</li>');   
						$('#movie-data').append('<li>Popularity : '+row.vote_average+'</li>');             
						$('#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){  
					movieInfo.result = result.results;
					$.each(result.results, function(i, row) {
						console.log(JSON.stringify(row));
						$('#movie-list').append('<li><a href='' data-id='' + row.id + ''><img src='http://d3gtl9l2a4fn1j.cloudfront.net/t/p/w185'+row.poster_path+''/><h3>' + row.title + '</h3><p>' + row.vote_average + '/10</p></a></li>');
					});
					$('#movie-list').listview('refresh');
				}
			}		
		</script>
    </head>
    <body>     
		<div data-role='page' id='home'>
			<div data-theme='a' data-role='header'>
				<h3>
					Movie List
				</h3>
			</div>        
			<div data-role='content'>
				<div class='example-wrapper' data-iscroll>
					<ul data-role='listview'  id='movie-list' data-theme='a'>
						
					</ul>
				</div>
			</div>
			<div data-theme='a' data-role='footer'>
				<h1>Copyright 2013</h1>
			</div>              
		</div>
		<div data-role='page' id='headline'>
			<div data-theme='a' data-role='header'>
				<a href='#home' class='ui-btn-left' data-transition='slide' data-direction='reverse'>Back</a>                        
				<h3>
					Movie Info
				</h3>
			</div>        
			<div data-role='content'>
				<ul data-role='listview'  id='movie-data' data-theme='a'>
					
				</ul>
			</div>
		</div>    
    </body>
</html>   
 
There’s only one last thing to do, we need to copy index.html into a previously cleaned project www directory.
 
Let’s proceed, next few lines will add the Andrpoid platform, build it, and run our demo Android project. Don’t forget to run next few lines in command prompt, inside a current project directory (in case of this example it’s C:\Android\Projects\testApp):
 
cordova platform add android
cordova build android
 
Now connect your smartphone and execute this:
 
cordova run android
 
This is how our demo application looks like:
 
jQuery Mobile Tutorial 1016
 

Conclusion

 
This article was meant to show you how last jQuery Mobile version runs and feels wrapped inside the PhoneGap/Cordova app. From what I can see it behaves much better than previous jQuery Mobile versions, CSS reductions really helped to make it more fluid and native-like. Page transitions finally feel native-like, unfortunately, scrolling still doesn’t feel fluid, still it is a big improvement over previous versions.
 

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:






  • TorchMan

    Hey Gajotres,

    nice article. SInce the last week, i’ve tried to integrate iScollView into my PhoneGap+JQM Projekt for Android.
    What i noticed is, that with iScrollView scrolling get’s choppy with large content. Have you experienced similar effects?

    • Yes I have, you can even see it in my app example. It just don’t feels native enough, that’s why I wrote “unfortunately scrolling still don’t feel fluid”. Also to be fair I wouldn’t put this on jQuery Mobile, at least not everything.

  • alamatpalsu2

    iOS/MacOS combination please?

  • Icebergdelphi

    Nice work, but i’ve been traying to launch into the virtual android and rise an error due that i put the index inside isset, but i realized that the isset directory has a www folder and inside www there are: css, img, js, res, spec, cordova,js, index,html and etc, if i replace the index,html for my index,html an issue appears, so what is happens? tnx.

  • Icebergdelphii

    Resolved: Application Error Is a directory (file:///#android_asset/www/index.html)
    what did I was, downloaded the jquery.mobile-1.3.0.js file and had it placed locally inside my www folder. That fixed my problem.
    I was using a resource that requires internet access as Jquery, etc.

    Tnx again.

  • Marcus

    Yes, thanks for a great article!
    I would also love an iOS/MacOS combination so I’m showing my interest.
    Cheers

  • Lisa

    Great article!

    I’m also showing my interest for a iOS/MacOS combination.

    Have nice day

  • vladislav

    Great! Would ask for IOS please

  • Joey

    Wish I had found this site earlier; would have saved me a day to see how jq mobile performs; thx!

  • Donny Firdhana

    Hi there,

    when I create project, I got error message says :
    “Error: ENOENT”, no such file or directory ‘c:\Android\Project…..’ –> just like you saying.

    anything wrong..?

  • Roshdy

    I followed this tutorial step by step, the only change is that i’m using the latest cordova 3.2
    However, i keep having this Error on the “create” application step
    [Error: An error occurred while listing Android targets]

    Please help!

  • Hi, just wanted to tell you, I loved this blog post. It was helpful.
    Keep on posting!

  • Glen

    Thanks for sharing. I wanted to let you know your webpage doesn’t display properly on Linux Mint using Firefox or Chrome. The whole page is shifted to the right, cutting off the ends of the content.

    • Thank you for this information, I will try to fix this as soon as possible.

  • al

    Very clear and concise, thank you.
    I have followed this tutorial to the letter and can not create a sample project. I wonder, is this a compatibility issue?

    I have installed all the soft in the last 2 days. It is eclipse, android sdk, ant, java sdk and done all the path system variables
    %ANT_HOME%\bin;%JAVA_HOME%\bin;%ANDROID_HOME%\platform-tools\;%ANDROID_HOME%\tools\;%PATH%\tools;

    Maybe there is some workaround? The answers to be found on the internet seem to address the matters I have sorted out, like run cmd as an administrator, set the paths, instal everything, no spaces in folder names…

    Please help.

    D:\DEV\ANDROID\cordova-3.4.0\cordova-android\bin>create d:\dev\Android\Project\PhoneGap_example com.test.example “grai5”
    D:\DEV\ANDROID\cordova-3.4.0\cordova-android\bin\node_modules\q\q.js:126
    throw e;
    ^
    Error: An error occurred while listing Android targets
    at D:\DEV\ANDROID\cordova-3.4.0\cordova-android\bin\lib\check_reqs.js:87:29
    at _rejected (D:\DEV\ANDROID\cordova-3.4.0\cordova-android\bin\node_modules\q\q.js:808:24)
    at D:\DEV\ANDROID\cordova-3.4.0\cordova-android\bin\node_modules\q\q.js:834:30
    at Promise.when (D:\DEV\ANDROID\cordova-3.4.0\cordova-android\bin\node_modules\q\q.js:1079:31)
    at Promise.promise.promiseDispatch (D:\DEV\ANDROID\cordova-3.4.0\cordova-android\bin\node_modules\q\q.js:752:41)
    at D:\DEV\ANDROID\cordova-3.4.0\cordova-android\bin\node_modules\q\q.js:574:44
    at flush (D:\DEV\ANDROID\cordova-3.4.0\cordova-android\bin\node_modules\q\q.js:108:17)
    at process._tickCallback (node.js:415:13)

  • al

    I had googled extensively before asking here and gone through also the site you recommend. Here is a summary of advice offered there:

    install apache ant.
    create two system variables ANDROID_HOME and ANT_HOME
    %ANT_HOME%\bin;%JAVA_HOME%\bin;%ANDROID_HOME%\platform-tools\;%ANDROID_HOME%\tools\;%PATH%\tools;
    install the latest Tools and SDK
    restart cmd and try again

    It appears this one advice to restart cmd could have made some difference, because now the response is different, but now there is a shell.js internal error.

    D:\DEV\ANDROID\cordova-3.4.0\cordova-android\bin>create d:\dev\Android\Project\PhoneGap_example com.test.example “grai8”
    Creating Cordova project for the Android platform:
    Path: ..\..\..\Project\PhoneGap_example
    Package: com.test.example
    Name: grai8
    Android target: android-19
    Copying template files…
    shell.js: internal error
    Error: ENOENT, no such file or directory ‘D:\DEV\ANDROID\Project\PhoneGap_example\assets’
    at Object.fs.mkdirSync (fs.js:642:18)
    at D:\DEV\ANDROID\cordova-3.4.0\cordova-android\bin\node_modules\shelljs\src\cp.js:173:14
    at Array.forEach (native)
    at Object._cp (D:\DEV\ANDROID\cordova-3.4.0\cordova-android\bin\node_modules\shelljs\src\cp.js:156:11)
    at Object.cp (D:\DEV\ANDROID\cordova-3.4.0\cordova-android\bin\node_modules\shelljs\src\common.js:172:23)
    at D:\DEV\ANDROID\cordova-3.4.0\cordova-android\bin\lib\create.js:166:19
    at setShellFatal (D:\DEV\ANDROID\cordova-3.4.0\cordova-android\bin\lib\create.js:45:5)
    at D:\DEV\ANDROID\cordova-3.4.0\cordova-android\bin\lib\create.js:164:9
    at _fulfilled (D:\DEV\ANDROID\cordova-3.4.0\cordova-android\bin\node_modules\q\q.js:798:54)
    at self.promiseDispatch.done (D:\DEV\ANDROID\cordova-3.4.0\cordova-android\bin\node_modules\q\q.js:827:30)

  • Nilesh

    Hi
    this article is good but its look and feel not working on android version less than 3.0 so
    how can i fix this issue? i did already post question on this issue see the following link

    http://stackoverflow.com/questions/21927537/jquery-mobile-listview-look-and-feel-not-working-android-2-3-3

  • hunt

    Nice tutorial but may I suggest using NetBeans 8.0? It has an awesome Cordova app support that simplifies a lot a big part of this tutorial! You can install it on a Mac and launch both Android or iOS simulators, upload to devices or debug directly in any system browser. Same should happen also on windows or linux, except the iOS support that requires a Mac+XCode build tools obviously!
    When creating a project, NB8 will also download jQuery Mobile or whatever js library you like directly in your project by selecting it from an updated cdn list. Really, give it a try and forget the eclipse headache 😉

    • Tnx for this info, personally I prefer NB over Eclipse but I didn’t know it received such kind of support. I will try it this weekend.

  • 4/4/14 Hi Gajotres.

    Thank you for the very clear post (everything worked great) and I am “phonegapping” LOL…

    Just an FYI. yesterday I found out and installed the “genymotion” Android emulator (free one).

    It is much (much) faster than the stock Android Emulator and makes the Phonegap Eclipse Genymotion” Emu” a much more natural workflow.

    There are paid for features with Genymotion that I know nothing about because there are fees involved (which is fine but I do not require these, yet). If needed, Google Play apps ‘n other google apps are not included in the stack and need to be added, if necessary. This tells you how to do it and it worked for me without incident nor error if followed exactly. (http://stackoverflow.com/questions/17831990/how-do-you-install-google-frameworks-play-accounts-etc-on-a-genymotion-virtu)

    No association with these folks other than being a new fan of their efforts and the much improved speed of developmetn achieved.

    Cheers //GregH from Huntington Beach CA

  • Leo

    For responsive website.
    http://webresponsivedesigns.com

  • Arvind Hindyar

    $.mobile.changePage( “#headline”, { transition: “slide”, changeHash: false });
    });

    does it work with query mobile 1.4 ???

    • It still works but it’s deprecated so be careful.

  • Visit

    I am truly grateful to the owner of this site who has shared this wonderful paragraph at at this
    time.

  • visitor

    that query has 60 results here is only 20

  • Simone

    Hi Dragan,
    thanks for this beautiful tutorial. I’m really new in phonegap and I noticed that in your app, when you click on the Android back button, also if you are visualizing the details of a movie, it exits from the app. This is intuitively not correct but it should allow to come back to the previous “activity”. Is there a way to do this? this happens because you are using only one html file and div to simulate other pages?
    Thanks

    • This is only a demo application, made to show you how jQuery Mobile works with Phonegap. If you have any non related question I would advise you to ask them over at StackOverflow, mainly jQuery Mobile group. Just ask for Omar.

  • Simone

    Hi Dragan,
    I have another problem. It’s a bit difficult to explain….when I want to see the last elements of the list it is impossible to select these elements because it seems like the height of the content is too small. If you try the app on a device you can understand.
    How can I solve this problem?
    Thanks

  • sunil

    Very useful tutorial for beginners . 🙂

  • Hafid Afridian

    Thanks a lot… My app run successfull..

  • jimmy

    Only Because of you Today I know how to make android and ios app thank you for teaching me such an awesome thing 🙂

  • Phanku

    Thank you for the great example. Could you please describe the best way to bind to phonegap’s events? I need to capture the backbutton event triggered by pressing Android’s native back button but I seem to keep running into race conditions with jqury mobile firing off before I try to bind to the event.

    • What part of jQuery Mobile is causing you problems? Describe me what’s happening.

      • phanku

        I see that some of the post was stripped out. I should have figured there would be some sanitizing.
        I have update the post. Please delete the previous post if you can. The edited example is below.

        I have to say right off the bat thank you.
        As I was writing my response to you I realized what I was doing wrong.

        I will post an example here of my solution.

        ::HTML JS inclusions::
        Jquery (2.1.1)
        handlebars(2.0.0)
        App (my script)

        phonegap (3.6.3)
        jquery mobile (1.4.5)

        ::app js::

        var app = {

        deviceready: $.Deferred(),
        jqmReady: $.Deferred(),
        jqmPageShow: $.Deferred(),
        initialize: function () {
        document.addEventListener(‘deviceready’, app.onDeviceReady, false);
        app.bindPageShow();
        $(document).one(‘mobileinit’, function() {
        — execute jquery mobile settings —
        app.jqmReady.resolve();
        });
        $.when(app.deviceready, app.jqmReady, app.jqmPageShow).then(function() {
        — hide splash screen —
        — bind to backbutton event —
        });
        },
        bindPageShow: function() {
        $(document).one(“pageshow”, function() {
        app.jqmPageShow.resolve();
        });
        });
        }
        };

        Thank you for your help. I would still like any feedback if you believe there is a better way to do what I am doing.

        There may be a typo in this code as I didn’t actually copy the exact code because it is rather long but this should give you the idea of how I solved my problem.

  • delphicoding

    Hi. Thank you for this clear tutorial. I have only one thing I’m not understanding: when I connect my device and run the app, the movies’ list is empty… I get the header ‘Movie list on a light grey background, the footer at the bottom but the list is a white, empty land… Any idea?

    • Have you received any errors in yoou console log?

  • Mahendra Singh

    hii,
    I’m new jquery mobile with phonegap. please give me any idea how can i build a jquery mobile cordova project and how can i build the apk

  • JimmyG

    Hi and thanks for the article its very helpful at this stage in my learning of mobile app development.
    I have gone all the way to the cordova and jquery install using the npm install -g cordova jquery-mobile command but after twenty minutes and just a blinking cursor below the command in my cmd.exe program its clear something is not right. I looked online but cant find any clues to date.
    I have come to think its the location of the C:Documents and SettingsJames Goodwin.npmrc (not C:Users{Username} as in tutorial above) The location of node and npm is the default install C:Program Filesnodejsnode_modulesnpm
    My system is Win XP SP3 any help would be much appreciated if you have the time.
    Judging by the answer below I shoud begin with OnsenUI and not Jquery Mobile anyway.

    Jimmy

  • Hi Jimmy. If you want my recommendation then switch to OnsenUI. While still technically alive, jQuery Mobile is dead technology. It’s simply outdated. On the other hand, Onsen UI (version 2.0) is platform agnostic so you can use it with any framework you prefer.

    If jQuery is what you want then you can use it, or AngularJs, it doesn’t matter.

    It’s also similar to jQuery Mobile in a way you build page structure. For example, if you’re AngularJS user you don’t need to do any page routing (like with Ionic Framework or vanilla AngularJS), everything is done automatically in the background.

    • JimmyG

      I’m going to take your advice Dragan thanks. Its deep end for me as I was familiar with JQMob but I’ve learned in my time in web development that choosing a platform that you can grow with which is well supported is the best way to go long term.
      I don’t have any experience in app development but I do see that html5 hybrid app development is attainable for me and this model is here to stay in the medium to long term. Apps built solely in native code will become less necessary as time goes on.

      Jimmy

  • Rohini

    Wow…tats brilliant. Please can you provide me with code for developing a directory app? Where people can search for various categories and services. Really would appreciate your help.

  • Yusri Aja

    Thanx for the tutorial. I works for me, but how do I change the Target SDK version . It provide me API 23 , i want to use 20, thanks for replay…

  • chant9

    Great tutorial, however when pressing the Back button on the Movie Info page the list briefly appears but then it jumps back to show the Movie Info page again. With the slide transition off it works perfectly, any ideas how to stop that? Thanks

    • chant9

      No worries, the demo is using a beta version of jquery mobile, the latest version works fine.

  • CorporateCorp Diseño

    Hi, thanks a lot for this tutorial…i need to make a button to close my app launcher…yes…my app was converted into a launcher, and i don´t know how to close it and change to android launcher default…i can close the app, but not the launcher…how can i do it using a button??? Thanks!!!!