Friday, August 31, 2012

Enterprise Strength Mobile JavaScript in LA & OC


I will be at LA C#.NET and SoCal.NET on Tuesday, September 4th and Wednesday, September 5th respectively. I will give the same talk to both groups on Mobile JavaScript development. If you are a mobile web developer, a desktop web developer, or just starting with JavaScript and want to avoid making mistakes, you should attend this talk. Here is the synopsis: Enterprise Strength Mobile JavaScript: Unit Testing and Debugging Mobile JavaScript in the Real World JavaScript has a well deserved reputation of be hard to write and debug. Put it on a mobile device and the problems increase exponentially. Mobile browsers lack all of the niceties that developers rely on to do testing and debugging including the most fundamental tool, the debugger. But it is possible to write quality JavaScript on a mobile device without relying on blind luck. In this talk I will show all of the tools and tricks that I learned in my 12 month development of the new KBB.com mobile site. For more information: LA C#.NET - 9/4/12 @ 6:00 PM SoCal.NET - 9/5/12 @ 6:30PM

Wednesday, August 29, 2012

Beginning jQuery Mobile - jQuery LA - Idealab



I had an amazing time last night at Idealab giving a presentation on Beginning jQuery Mobile. I want to thank the good folks from jQuery LA for inviting me and being such a great audience. And also to thank our host Idealab. They have an absolutely beautiful building and were extremely kind to us, even when we ran long with questions at the end.


Here are the links to the slides and source code:



If you attended please take the time to rate my talk:


Tuesday, August 21, 2012

Enterprise Strength Mobile JavaScript Slides

Here is the link to the slides for my presentation on 21 August 2012 for the Society of Software Quality - San Diego Chapter:

Enterprise Strength Mobile JavaScript Slides

Saturday, August 18, 2012

Updated Skeleton

I've updated JQM Skeleton to use a lot of the features that I've written about in other posts. Here is the quick list of the modifications: 

  1. Kernel Framework code clean up
  2. Kernel Framework no longer uses .live()
  3. Inclusion of the Dimension() method for sizing the content area 
The updated code is in my repo on GitHub.

Source Code for JQMSkeleton

Friday, August 17, 2012

Testing Browsers - HTML5Test & CSS3Test

Sometimes your web application doesn't work and it might not be your fault, sometimes it is the browser's fault. No browser supports every feature of  HTML5 or CSS3. 

Determining which features your phone's browser supports use to be tedious. You would have to write code to test each feature you were interested in. If a test failed you would have to double check your code to be sure that it was written correctly. Luckily we don't have to do that any more. Nowadays there are websites available which will exercise nearly all of a browser's features. All you have to do is type their URL into your browser. My two favorite test sites are also super easy to memorize: HTML5Test.com and CSS3Test.com.

Both do exactly what their names say. They test your browsers implementation of HTML5 and CSS3 feature respectively. This is really important to do while your site is still in the design phase. You can see if see if your desired features are supported by your target devices. 

Here are pictures of HTML5Test.com running on my iPhone (iOS 5.1), Nexus One (Android 2.3.6), and Samsung Focus Flash (WP7.5):


HTML5Test.com uses a score based system. The maximum possible points is 500. As you can see there is wide differences in the scores. The Focus Flash while a great little phone definitely has some issues supporting higher end browser features.


CSS3Test.com uses a percentage based system. The maximum is 100%, obviously none of these phones is close yet. Be sure to try these sites in your phones browser.

Tuesday, August 14, 2012

Dynamic jQuery Mobile Pages Without ".live()"

In jQuery 1.7 .live() was deprecated. All good jQuery and jQuery Mobile coders should no longer use it. But how to replace it? .live() was a very powerful way to bind events. Set it once and until the end of your application's life the event was bound. Load new DOM fragments from your server or generate them dynamically in JavaScript and they would have events magically bound to them just like their older brethren. 

I don't want to argue whether .live() should have been removed or not, I only want to present a different way to dynamically bind to pages. Until recently I had been using .live() to bind page events in my jQuery Mobile applications framework. Being a good coder I replaced .live() with .on() and promptly broke my code. Everything worked for the internal pages but externally loaded ones no longer got page events.

The Old Way

The old framework relied on .live() to feed all of the page events to the kernel. The code is as follows:


It was a simple as could be. The .live() call hooked all of the desired page events and sent them to the Kernel method. Didn't matter whether the page was loaded or not at the time of the call.

The New Way

The new way isn't as elegant but it isn't hideous either. First I did a bit of clean up. I wasn't using all of the events that I was hooking so I removed the unused ones. I was left with the following events:

pagebeforeshow pageshow pagebeforechange pagechange pagebeforehide pagehide

Then I released that all I needed to know was when a new page was loaded. Once it was I could just use .on() to hook events again. To be safe I would call .off() before calling .on() to be sure that I wasn't double hooking events. 

It turns out that when jQuery Mobile loads a new page into the DOM it triggers a pageload event on the document. All I needed to do was to hook it and I was in business.

The biggest change is the addition of the method Rockncoder.Pages.Evs(). It hooks the "pageload" event of the document. When it is trigger it clears all currently hooked page events and then re-hooks them using .on(). Other than a little code clean up that it. 
The beauty is that it all works dynamically without .live()

As an added bonus I also demonstrate how to dynamically load JavaScript which still works within the framework. Page 2 loads the JavaScript for page 3 if it has not been previously loaded. Then when page 3's link button is clicked it will call via the framework, its event handler code.


RocknCoder.Pages.page2 = (function () {
    var pageshow = function () {
       alert("page2 show");
       },
               pagebeforeshow = function () {
           // dynamically load the script for page 3
   // if it hasn't already been loaded
   if (!RocknCoder.Pages.page3) {
       $.getScript("scripts/page3.js");
   }
   alert("page2 beforeshow");
       },

That's all for this post. The complete source code is on GitHub. 

Source Code for JQM DynamicPages

Monday, August 13, 2012

Enterprise Strength Mobile JavaScript


On August 21st, I will be giving a talk to the Society for Software Quality, San Diego Chapter. The working title for the talk is:

Enterprise Strength Mobile JavaScript:
Unit Testing and Debugging Mobile JavaScript in the Real World

JavaScript has a well deserved reputation of be hard to write and debug. Put it on a mobile device and the problems increase exponentially. Mobile browsers lack all of the niceties that developers rely on to do testing and debugging including the most fundamental tool, the debugger. But it is possible to write quality JavaScript on a mobile device without relying on blind luck. In this talk I will show all of the tools and tricks that I learned in my 12 month development of the new KBB.com mobile site.

If you are building or thinking of building mobile apps in JavaScript, you need to attend this talk. The doors open at 6 PM, my talk begins shortly after that. For more information visit the Society for Software Quality, San Diego Chapter.

Location:New Horizons
7480 Miramar Road

Building B, Suite 202
San Diego, CA 92126
858-880-2200
August 21, 2012 at 6PM



Sunday, August 12, 2012

jQuery Mobile and AdSense



You and your team create a beautiful and engaging mobile website. Your visitors, page views, and site duration numbers keep increasing, but how do you turn that into cash? Like it or not one of the easiest ways to turn page views into cash is ads. That's right ads, those annoying things that all users seem to hate but are the most universal way to pay the bills.

In this post I show how to integrate Google AdSense into a jQuery Mobile web site. Please know that AdSense is not the only mobile web ad provider, there are others and I would highly recommend investigating them before committing to AdSense.


Like so many things Google there is a "Getting started" page. It is a little bit hard to find since most search queries for mobile ads will send you to AdSense's cousin, AdMob which is intended for mobile device apps. Be sure to read all of the program policies. You and your site will be held responsible if you violate any policy. 

Next you will need to sign into AdSense with a Google Account, aka your GMail account. If you don't have one you will need to get one which is relatively easy to do. Be aware that this account will need to be verified. Since AdSense will hopefully be sending you money, both your identity, address, and banking information will need to verified.

Once you are in AdSense do the following:

  1. Click the My ads tab
  2. Make sure that Ad units is selected in the left column
  3. Click the + New ad unit button
  4. Give the ad unit a name, I chose, BlogDemo
  5. Set the Ad size, choose 320 x 50 - Mobile Banner
  6. Make sure that Text & image/rich media ads is selected
  7. For Backup ads, just leave it set to Show blank space
  8. Don't worry about Custom channels
  9. Leave the Ad style set to Google default
  10. Click the button Save and get code
  11. Copy the Ad code


The Ad code will look something like the following:

<script type="text/javascript"><!--
google_ad_client = "ca-pub-################";
/* BlogDemo */
google_ad_slot = "6806436256";
google_ad_width = 320;
google_ad_height = 50;
//-->
</script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>

There are two parts to the Ad code, the first part should go in the header of each page which will display an ad. The second part should go where the ad will be displayed. In the first part is your Google Ad Client Publisher Id. You must replace the number shown with yours. The number shown above will not work in code.

To demonstrate how to plug the ad code in, let's create a simple two page mobile website. If you've read this blog before, you might recognize this as our jQuery Mobile Skeleton. It makes a good place to start our coding.

Where should we display the ad? Since the ad is 320 x 50, it will stretch the width of the display on iPhones and many other smart phones. Obviously we don't want an ad appearing over out content. It would be least bothersome either at the top or the bottom of the page. Or in jQuery Mobile parlance, it will be best if was in either in the header or the footer. And that is exactly what we will do.

First we place the first part of the Ad code in the head section of both pages:

<script src="scripts/jquery-1.7.1.min.js" type="text/javascript"></script>
<script src="scripts/jquery.mobile-1.1.1.min.js" type="text/javascript"></script>
<script type="text/javascript"><!--
        google_ad_client = "ca-pub-################";
        /* BlogDemo */
        google_ad_slot = "6806436256";

        google_ad_width = 320;
        google_ad_height = 50;
        //-->
</script>

On page one we will place the ad in the footer like so:

<footer data-role="footer" data-position="fixed">
        <script type="text/javascript"
                src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
        </script>
</footer>

Notice that we use the data-position="fixed". That will lock our ad at the bottom of the display.

On page two, we place the ad in the header like so:

<header data-role="header" data-position="fixed">
        <script type="text/javascript"  data-ajax="false"
                src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
        </script>
</header>

The last thing we need to do is force page loads. AdSense was created for websites which load pages the old fashion way. It uses the HTML <script> tag to inject JavaScript and HTML onto the page. If the script tag is loaded via ajax, the magic doesn't occur. To get this behavior in jQuery Mobile, we must turn ajax off via the data-ajax="false" attribute.

<a href="index.html"  data-role="button" data-ajax="false">to the Index page</a> 

Unfortunately, while the data-ajax allows AdSense to function correctly, it causes us to lose the jQuery Mobile transition effects. If anyone has found a way around this, please let me know.

The code for this post is on GitHub as always. Keep in mind that it won't work until you put your publisher information in.


Friday, August 3, 2012

jQuery Mobile - Dynamic Content Area Sizing


Normally web apps are told to simply use document flow to position controls. This way they are able to automatically adjust based on the size of the display. This sounds good on paper but doesn't look so good in real life. Today's web apps especially mobile web apps are judged as much on their form as they are on their function. Knowing the size of the content area makes it easier to place controls using percentages or even pixels, if you are into that kind of thing.

Content Area Sizing

How do you determine the size of the content area? It actually isn't too difficult. Since jQuery Mobile is built on top of jQuery, we have access to jQuery's dimension methods. Determining the width is super simple:

var width = $(window).width();

That's it. Please note that I cache the results into a variable. Searching the DOM is very slow. One of the quickest performance improvements you can make in jQuery or jQuery Mobile code is to cache the results of selectors into variables.

Determining the height is a little trickier. To determine the height of the window is as easy as it was with the width:

var height = $(window).height();

The trick comes with the header and footer. The height of content area changes when one, both, or none of them is present. Luckily that is easy enough to determine as well.

hHeight = $('header').outerHeight() || 0,
fHeight = $('footer').outerHeight() || 0;

Here we take advantage of the JavaScript default operator, also known as the logical or. If the value returned by the selector is null or undefined or something else which is equivalent to false, the variable will be assigned a zero. Also note that we use outerHeight() not height(). We use outerHeight(), because we want the padding and margin too.

The iPhone Problem

There is one last thing that we do which needs explaining. I normally hate to put device specific code in my apps. This is the first exception. The height returned by the iPhone always wants to include the URL bar, even when you have it hidden. I haven't figured out a way around this issue. So now I do a simple, and possibly flawed, detection method for the iPhone. If it is detected we add 60 pixels to the height. I tried for an embarrassingly long time to fix this issue without success. If you have a better workaround, please let me know.

var isIPhone = (/iphone/gi).test(navigator.appVersion),
iPhoneHeight = isIPhone ?  60 : 0,

The Main Events

The final piece of the puzzle is the events. jQuery Mobile documentation will state that you should use the pageinit event to start your own code. In most cases this is true, but since we also want the page to be displayed, we need to wait for the pageshow event. Once we receive it, we know that the header and footer have been rendered. We also want to know when user rotates the screen so we trap the orientationchange event as well. The final event we bind to is the resize event. This is not strictly necessary, since it isn't normally possible to resize a browser window on a mobile device, but I know a lot of people will run the code on their desktop.

The Code

Both the markup and the code for this demo are very simple. An orange div will resize itself to fill up the available content area minus 2 pixels around the edges. In your own app you could potentially place your controls within the div and position them using either a grid or percentages.

Here is the link to a working demo of the app: JQM Resize.
All of the source code is on GitHub: JQM Resize Source Code