Archive for the ‘Mobile’ Category

Single finger scrolling in Mobile Safari

Tuesday, June 21st, 2011

We built the BackChannel using the Mobile View Engine I discussed in this post. If you hit the site with a phone we serve a mobile version, but if you hit it with a tablet, we serve the full version, which, of course, we expect to work. For the schedule page, I built a nifty full screen multi-pane interface that works perfectly in all desktop browsers I tried and in the Android 3.1 browser on my Xoom. But yesterday Dave pointed out that the bottom left and right panes wouldn’t scroll on iPad.

After a little digging, I found that Mobile Safari doesn’t support single finger scrolling on divs. You have to use two fingers. This is actually documented in the iPad User Guide. Presumably this is because on touch based devices it’s hard to know if you intend to scroll the whole page or just the div. But, like I said, it works perfectly on my Xoom. Now, if I didn’t know this, I certainly can’t expect my users to.

I found that Nick Larson had created a very simple fix to implement single finger scrolling. I took it and rolled it into a jQuery plugin (my first, actually) using Mike Alsup’s plugin pattern. There are other solutions out there but mine has the virtue of being very easy to understand and very light (644 bytes minified).

/*mjuniper 06/21/2011
    based on code from:

http://www.flexmls.com/developers/2011/04/13/

ipad-and-single-finger-scrolling-in-flexmls/
    and http://www.learningjquery.com/2007/10/a-plugin-development-pattern
*/
//
// create closure
//
(function ($) {
    //
    // plugin definition
    //
    $.fn.mobileScroll = function (options) {
        //only do it for iOS devices
        var userAgent = window.navigator.userAgent.toLowerCase();
        if (userAgent.indexOf('ipad') > -1 ||
                userAgent.indexOf('iphone') > -1) {
            this.bind('touchstart', function (evt) {
                var e = evt.originalEvent;
                startY = e.touches[0].pageY;
                startX = e.touches[0].pageX;
            });

            this.bind('touchmove', function (evt) {
                //need the touches property of the native dom event
                // - jquery exposes originalEvent for that
                var e = evt.originalEvent;
                var touches = e.touches[0];
                //cache $(this)
                var $this = $(this);

                // override the touch event’s normal functionality
                e.preventDefault();

                // y-axis
                var touchMovedY = startY - touches.pageY;
                startY = touches.pageY; // reset startY for the next call
                $this.scrollTop($this.scrollTop() + touchMovedY);

                // x-axis
                var touchMovedX = startX - touches.pageX;
                startX = touches.pageX; // reset startX for the next call
                $this.scrollLeft($this.scrollLeft() + touchMovedX);
            });
        }

        return this;
    };
    //
    // end of closure
    //
})(jQuery);

ESRI UC BackChannel is live!

Wednesday, June 15th, 2011

We’re still tweaking but the BackChannel app for the 2011 ESRI International User Conference is live! We’ve had tons of fun building this app; we hope you enjoy it.

Collapse the iPad Keypad in Javascript

Tuesday, April 26th, 2011

I recently built a web application with a search field which geolocates whatever you typed into that field and zooms you to the results. We were severely constrained on UI space so we went without a search button and we just do the search when the user hits the enter key.

This worked fine on the iPad except that the keypad didn’t collapse. Of course, you can’t directly control the keypad in Javascript but I had a hunch that if I just removed focus from the search field, it would collapse. And it worked! Code (jQuery) below:

$(this).blur();

iPad and Motorola Xoom – a tale of two browsers

Tuesday, April 26th, 2011

We recently built a web application (several actually) that we needed to work well on tablets. Since the first Android 3.0 (Honeycomb) tablet, the Motorola Xoom, is now out (and since I have one) we were specifically targeting the iPad and the Xoom. Though they both use Webkit based browsers, I ran into a couple of interesting differences between the two.

First off, I used -webkit-user-select:none; to prevent selection of various elements in the ui. This worked flawlessly in Mobile Safari on the iPad but Chrome on Android does not seem to respect it at all.

I also ran into a couple of issues using the ArcGIS Javascript API on the Xoom. Since Android doesn’t support SVG, the JSAPI uses canvas and there are evidently some small problems with their canvas implementation. TextSymbol doesn’t work and neither do any of the fill styles for simple fill symbol except solid and null. Overall the JSAPI works great on the Xoom, though.

I’m told that the text symbol issue will probably be fixed in the 2.3 release.

Mobile Device Detection and Android

Tuesday, March 15th, 2011

We’ve been doing more and more apps for mobile devices. Specifically we’ve built some apps recently that we want to work from desktop browsers, tablets, and smartphones.

I’ve heard the argument that you should just serve good semantic html and style it appropriately for the device and be done with it. But we’re not building content driven websites, we’re building data driven web apps often containing maps. We need to give the user an entirely different experience on a phone vs a desktop browser.

We’re using a custom mobile view engine in ASP.NET MVC (based on the one in this Scott Hanselman post) to serve the appropriate view for the requesting device. That’s been working great but one problem I’ve run into is how to distinguish an Android tablet from an Android phone. I finally found the solution to this problem on the Android Developers Blog. Basically, if a device runs android, it should contain the string “android” in the User-Agent string. Google recommends that “manufactures of large-form-factor devices (where the user may prefer the standard web site over a mobile optimized version) remove ‘Mobile’ from the User Agent”. That would be great except that Motorola has already screwed this up by including “Mobile” in the User-Agent of the Xoom.

The Request.Browser object in ASP.NET has a bunch of properties that tell you about the requesting device. But it’s not really sufficient (and some of it is just plain wrong or absent) for accurately identifying the capabilities of mobile devices. So we’ve started using 51degrees.mobi. It uses the WURFL database, which seems to be the most complete and up to date database of mobile devices, to populate tons of useful info on the Request.Browser object. One thing I didn’t realize at first is that besides accurately populating the existing properties of the Request.Browser object, it also makes available many of the other properties exposed by WURFL. They can be accessed like so: Request.Browser["is_tablet"]. We’re now using that in conjunction with the custom mobile view engine.

There are two drawbacks to the 51degrees.mobi component: It adds some overhead to every request. I haven’t really seen a lag but it’s gotta cost something. The more significant drawback is that you have to manually update the WURFL XML file.

Update: I don’t know if I was mistaken about the Xoom’s User-Agent or if Motorola has fixed it in a later revision but I now own a Xoom and the User-Agent does not contain “mobile” (which is correct, it should not). Also, the 51Degrees.mobi component is now available via NuGet, which, if you use Visual Studio, you should be using.