LavaBlast Software Blog

Help your franchise business get to the next level.
AddThis Feed Button

Gotcha: iPad versus ASP.NET

clock May 29, 2011 14:19 by author JKealey

Your web app looks awesome on the iPad, until…

FranchiseBlast: Franchise Intranet on iPad You decide to save it to your home screen.

If you’re doing this with a web application you’ve developed, you probably want to make it appear a bit more like a native app,  so you’ll add two meta tags to make the experience nicer (add an app icon and remove the navigation bar). Remember: Safari caches these tags when creating the shortcut, so you will need to delete/recreate the shortcut to force it to refresh.

Everything will look fine, until you reload the web app on some other occasion: ASP.NET Ajax is now completely broken and many of your styles are missing. Simply put, an application that worked fine when you shut down your iPad minutes ago will be completely unusable. No amount of refreshing will solve the issue. Clearing Safari’s cache and using it outside of the home screen icon is the only workaround.

Gotcha: Safari uses different HTTP User-Agent strings depending on context!

The iPad (and iPhone/iPod Touch) don’t use the same HTTP User-Agent string when a website is accessed normally via the Safari application versus a webpage that was saved to the home screen (which still uses Safar internally). Here’s an example:

  • Normal Safari: Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2
  • Website as app: Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Mobile/8J2
    ASP.NET doesn’t recognize the latter as being Safari – it recognizes it as a generic browser with no capabilities. As an example: Supports JavaScript? Nope.
    Add this hack to your base page to fix it. It makes ASP.NET think that anything based on AppleWebkit is a newer browser – a much better default setting (for most of us) than assuming the browser was created back in 1994.
       1:     protected void Page_PreInit(object sender, EventArgs e)
       2:      {
       3:          if (Request.UserAgent != null && Request.UserAgent.IndexOf("AppleWebKit", StringComparison.CurrentCultureIgnoreCase) > -1)
       4:          {
       5:              this.ClientTarget = "uplevel";
       6:          }
       7:      }

The long answer

On and off over the course of a month, I spent dozens of hours investigating this issue. In the end, the fix is trivial and updated *.browser files will probably be produced by Microsoft over the next months/years. However, I did learn a lot about how to debug a web-app on the iPad in the process, and thought I’d share a few lessons learned. I’ve kept them purposefully brief as you can easily find detailed answers on Google or StackOverflow.

Enable Safari’s Developer Debug Console

That’s how I figured out ASP.NET AJAX wasn’t loading properly. Was getting JavaScript errors that you normally get when ASP.NET Ajax is not properly configured in the web.config file.

  • On the iPad: Settings –> Safari –> Developer –> Debug Console (on)

Install Firebug Lite on your iPad

I frequently use Firebug on my desktop computer to analyse web pages. The lite version on the iPad helped me review the HTML/JavaScript in greater detail. Install this bookmarklet (found it painful to do) then install the FireBug Lite bookmarklet. More info here.

Setup an HTTP Proxy

This helped me get in-depth information about exactly what HTML/JavaScript was being served in response to which HTTP Headers. That’s how I realized certain scripts were not being included when the User-Agent changed.

  • As I develop on a Windows machine, I made it run through Fiddler on my desktop. Other options found here.
  • In Fiddler, Tools > Fiddler Options > Connections –> Allow Remote Computers To Connect. Restart Fiddler. (Not working? Check Windows Firewall.)
  • On the iPad: Settings –> Wi-Fi –> Click on the right arrow for your connection –> HTTP Proxy –> Manual –> Set Server and Port. 

Other limitations worth knowing about

As everyone knows, Flash doesn’t work on the iPad/iPhone/iPod. It doesn’t come as a surprise to use that we have to eliminate it from our app (not a big detail for us).

However, one gotcha that had not come to mind initially is that certain JavaScript functionality such as click&drag or drag&drop does not work on the iPad given the differences in gestures between a conventional computer and a tablet. That code needs to be rewritten.

Did you experience any issues you’d like to share?



Re-skin your existing web app using jQuery Mobile

clock May 24, 2011 15:44 by author EtienneT

IMG_3337Recently, for a new franchise client of ours, we had to add some new features to our web-based point of sale system.   This piece of software makes extensive use of touch screen functionality; we need to think about this when we design our UI.  The interface must be optimized to allow cashiers to perform their operations effectively and intuitively with a touch screen.  Our application isn’t traditionally used via a multi-touch interface like the iPhone or iPad; rather, operators use a traditional touch screen. In this project, we had to adapt existing pages and create completely new modules.

In the past, we had played with jQuery Mobile and we were really impressed.  Take a look at the demo site – all you need to do is including a reference to jQuery Mobile’s JavaScript and follow some conventions with your HTML to get a nice mobile-friendly user interface. However, when you think about it, mobile-friendly (touch friendly) user interfaces are also very appropriate for traditional touch screen technologies utilized by the retail industry for over a decade.

Given our point of sale was initially created to be compatible with IE6 back in the day, we felt it was time to enhance the look and feel utilizing new technologies. We liked jQuery Mobile’s look & feel and wanted to utilize some bits & pieces, without having to re-implement everything following their conventions.  When you peek at the jQuery Mobile source code on GitHub, you realize that each component is separated in it’s own little jQuery plugin.  Some plugins are not completely independent from the jQM (jQuery Mobile) page, but you can use most of them outside of that context; you can thus use them in your own applications without a jQM page that takes 100% of the screen real estate.  In a typical jQM scenario, you define a page and then jQM works it’s magic: it initializes all the controls for you - if you followed the conventions. In this post, we’ll cover using jQuery Mobile outside of the jQM page and mobile context.

How to trick jQuery Mobile

First, you simply have to trick jQM into thinking that there’s a jQM page in the HTML.  To do that, you have to bind to a special jQM event, mobileinit.  This is event is executed before any jQM code modifies your html:

$(document).bind("mobileinit", function ()
{
    if ($('div[data-role=page]').length === 0)
        $('<div data-role="page" id="pageTemp" style="display:none;"></div>').appendTo($('body'));
 
    $.mobile.ajaxEnabled = false;
 
    $('#pageTemp').live('pagebeforecreate', function (event)
    {
        return false;
    });
})

Here you insert a jQM page in your html if one hasn’t already been defined. This is required for some controls to work (like the dropdown list, if I remember correctly). We then disable AJAX page fetching and also disable the 'pagebeforecreate' event for the newly created dummy page.  Most of our pages utilize this placeholder (as we only use the UI controls), but we did – on a few occasions - utilize the standard jQM page in all its glory inside our point of sale. 

If there’s a better way to do this, please let us know - with the current version of jQuery Mobile (1.0a4.1) it appears to be working pretty well.

Interesting controls

The plugins we found most interesting were the one dealing with forms controls. You can see a gallery of all forms elements in jQuery Mobile here.

For example, some of the base HTML controls are not ideal in the context of a touch-enabled application. Take radio buttons, for example. They are way too small and hard to click on accurately - you have to manually change their styling via CSS to make them easy to touch.  Here is the jQM version of radio button list:

Radio Button List

radio

To create this, first you need a little bit HTML plus the checkboxradio plugin from jQuery Mobile:

<fieldset data-role="controlgroup">
    <input type="radio" name="radio-choice-1" id="radio-choice-1" value="Cat">
    <input type="radio" name="radio-choice-2" id="radio-choice-2" value="Dog">
    <input type="radio" name="radio-choice-3" id="radio-choice-3" value="Hamster" checked="checked">
    <input type="radio" name="radio-choice-4" id="radio-choice-4" value="Lizard">
</fieldset>

Basically the fieldset groups the radio input together and gives the rounded corners only to the top and bottom items.

Then you can add this JavaScript to your page:

$('input[type=checkbox], input[type=radio]').filter(function ()
{
    return $(this).parent('.ui-checkbox').length == 0;
}).checkboxradio();
$("fieldset[data-role='controlgroup']").not('.ui-controlgroup').controlgroup();

This piece of JavaScript will select all checkboxes or radios inputs, filter the ones we already applied the plugin and then call checkboxradio() to change them to follow the jQuery Mobile style.  We then use the controlgroup plugin to group the controls together visually.  Once again we don’t re-apply this code to fieldsets that were changed previously, for efficiency reasons.

For an horizontal look, simply add data-style=”horizontal” to the fieldset grouping the elements.  It is still a radio button list, but the layout is different.

radio-horiz

Checkbox list

You can even do the same thing with checkboxes:

checkboxes

Suddenly, your UI becomes much easier to use with a touchscreen.

Dropdown

Here is a dropdown list, in the jQuery Mobile style:

dropdown

You simply execute the following JavaScript code:

$('select:not([multiple="multiple"])').selectmenu();

We had some problems with multi-selection lists, so that’s why we don’t automatically style those.

Button

Buttons are pretty straightforward. In our application, we decided to automatically transform all of our buttons which utilize the CSS class ‘button’.  This could be an input[type=button], input[type=submit], a simple link <a></a>.  We’re using a mix of these in our application and modify them all like this:

$('.button').not('.ui-btn').button();

buttons2

Above, the two buttons are inline (add the data-inline=”true” attribute to the HTML elements). The Save button has a different theme (specify data-theme=”b”)

buttons

You can also group buttons as above, by defining a horizontal controlgroup.

<div data-role="controlgroup" data-type=”horizontal”>
    <a href="index.html" data-role="button">Yes</a>
    <a href="index.html" data-role="button">No</a>
    <a href="index.html" data-role="button">Maybe</a>
</div>

Working with controls

Visit this page to know operations you can do on your controls once they are modified by jQM: Form Plugin Methods. This reference is very useful if you want to enable/disable controls or refresh them with new values.

ASP.NET WebForms

If you are using ASP.NET WebForms as is our case, you want to run these plugins every time your page is modified.  If you are using ASP.NET UpdatePanels, then you can bind a function to the following event handler where you could modify your controls each time an UpdatePanel is updated:

Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(function()
{
    // Add the jQuery Mobile code modifing controls here
});

Normally this job is done automatically by jQM, but since we are not using the controls inside a jQM page, we have to update the DOM manually after each postback.

Caveat

In its current form, jQuery Mobile is not compatible with Internet Explorer. Depending on the version of IE, it is easier completely unusable or doesn’t look as good (rounded corner issues). In our context (point of sale), we ended up utilizing Google Chrome Frame for our IE users – at least for the time being. The jQM team appears to be working towards full IE support for their beta release.

Future of jQuery Mobile

In conclusion, we loved working with jQuery Mobile once we figured out how to utilize bits & pieces of it individually. Currently, jQM focuses on development for mobile devices (which is normal) but we would be thrilled if they made integration into existing projects simpler. As this is an open source project, we weren’t afraid to peek at the code to figure out why it wasn’t working the way we intended it to. Let’s hope the project keeps on improving both its modularity and the desktop-based functionality.  Thank you to the jQuery Mobile team, continue the great work!



Month List

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2017

Sign in