Apr 11, 2012

Proper referencing of PhoneGap with JQuery mobile

Ok, so you've setup Eclipse, Android SDK, PhoneGap or XCode and you want to use best from the two javascript libs:
  • PhoneGap
  • JQuery Mobile
JQuery Mobile is not just another JQuery plugin. So you don't just reference it and use it per scenario.
After its loading it runs asynchronously number of tasks to change DOM structure so it fits into JQMobile UI layout conventions.
Bottom line is that any other yours peace of javascript has to be put in proper place inside this JQM model or you won't get results you expect.

How to reference PhoneGap with JQuery Mobile?

It depends what and mostly when you want it to be done.
If you need to run it as the very first thing before JQM and you don't need nothing from JQM for this task you must reference it on the top before referencing JQM library like this:
<head>
...
  <script type="text/javascript" >
    function OnDeviceReady() {                    
                      // Do something when PhoneGap is initialized
                }
     $(document).ready(function(){
                document.addEventListener("deviceready", OnDeviceReady, false);
   });
   </script>
   <script type="text/javascript" src="jquery.mobile-1.0.1.min.js"></script>   
 ...
</head> 


Now this will work but there is a catch. Both PhoneGap and JQmobile libs are based on event driven model. They run bunch of task in their own processes asynchronously. What this means is that when you tell PhoneGap that you want OnDeviceReady executed it will not be executed until phonegap in separate thread says I'm ready.
After line:
          document.addEventListener("deviceready", OnDeviceReady, false);
; execution continues and JQM starts to kick in. So they run parallel and no one can tell will OnDeviceReady really get executed before JQM starts.
Now someone will say that this is exactly what is expected from async process to behave but its just not plain obvious when you start to play with this things.

Hence I figure out I'll have to do some more reading on JQM :)

To cut long story short as a manual for lazy developers, like I'am, here it is.


<div id="MyPageUniqueName" data-role="page" data-theme="e">        
        <script type="text/javascript">
            $("#MyPageUniqueName").bind("pagebeforecreate", function (event) {

                  function OnDeviceReady() {                    
                      // Do something when PhoneGap is initialized
                }
                document.addEventListener("deviceready", OnDeviceReady, false);

});
</script>
...

JQM recommends injecting your code in appropriate JQM events. Read JQM docs for details on events and their purpose.

Although in proper place this code still does not guarantee that OnDeviceReady will get executed before JQM thread kicks in.

This represents a problem only if you need PhoneGap to prepare some stuff BEFORE JQM starts.
For example you need to obtain some data from mobile device internal storage using phonegap, inject it to DOM of page and let JQM render UI with new data.

Although you could try to wait using setTimeOut() while PhonGap loads and do its work and then let go JQM continue it is simple not right approach.

Right approach is to have Page A that prepares DATA using PhoneGap and then POST's this DATA to PageB. Page B then does not care about when PhoneGap is loaded since it already has its required DATA and can render it in proper JQM event PageBeforeCreate.












No comments:

Post a Comment