Enhancing the SharePoint 2010 UI: Scripted Orientation Aware Content

In my previous post we looked at enhancing the SharePoint 2010 UI through CSS based orientation detection. In this post, we will take it one step further and use some client side script to detect orientation and output content accordingly.

The CSS approach utilizes orientation aware style sheets which are loaded based on the appropriate orientation of the device (in this case an iPad). While this approach is simple to implement, it's not necessarily the most robust solution or the most scalable solution. The CSS approach is best suited to deployment with your site's branded master page, when orientation detection is a big part of your design. What if you only wanted it on one or two pages of your site, if you don't have access to deploy a new master page, or if you want more advanced orientation detection?

An alternative approach is to use client side scripting to detect the device orientation and process contextual changes for specific orientations. Another advantage to a scripted approach is that we now have some more information from the browser. The CSS approach simply looks for portrait vs. landscape, while the scripted approach gives us an integer value of the device orientation (0, 90, 180, or -90). Note that the browser gives us a value of "-90" as opposed to the "270" you'd expect to see when talking about rotation.

So to get started I'm going to create two div's in my design, one with an ID of "OrientationAlert" which we'll use to tell the user that more content is available if they rotate the device, and another with an ID of "SampleContent" to contain the demo content.

HTML:

<div id="OrientationAlert">Rotate device to landscape to view additional content.</div>
<div id="SampleContent">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean rutrum ligula sed diam porta eleifend vitae sodales nisl. Nam hendrerit sodales mattis. Vestibulum dictum, erat sit amet sodales dignissim, libero est vulputate sem, sit amet mollis justo sapien mattis dolor. In semper velit ut urna luctus pharetra. Cras pellentesque enim in massa laoreet mattis. Ut consequat, mi quis tempor ultrices, velit urna vestibulum metus, sed tempor nisl magna quis tellus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse id eros turpis, quis faucibus quam. Donec tempus pretium mollis. In posuere, magna sit amet facilisis porttitor, lorem libero pretium libero, ut tempus neque tortor vitae eros. Proin nec neque sapien, vel convallis nisl. Donec ut nulla at ligula semper laoreet sed quis metus. Vivamus pretium turpis sit amet nibh laoreet non interdum dui accumsan. Fusce mollis, velit eget lobortis vestibulum, metus est malesuada justo, ac tempus est eros et purus. Aliquam non leo nisl, nec viverra elit.</div>

Next we'll put in some Javascript to do the work. Note that we're also calling jQuery to simplify things; simply put the jQuery library somewhere in your site and link to the appropriate path.

Javascript:

<script type="text/javascript" src="/Style%20Library/jquery-1.4.2.min.js"></script><script type="text/javascript">// <![CDATA[
    // Boolean; is device an iPad or not
    var isiPad = navigator.userAgent.match(/iPad/i) != null;
    if (isiPad) { // Process only for iPads
        ProcessOrientation(window.orientation); // Process initial orientation
        window.onorientationchange = function() { // Process on orientation change
            ProcessOrientation(window.orientation);
        }

        function ProcessOrientation(curOrientation) {
            if (curOrientation == 0 || curOrientation == 180) {
                // Portrait Orientation
                $("#OrientationAlert").show();
                $("#SampleContent").hide();
            } else if (curOrientation == 90 || curOrientation == -90) {
                // Landscape Orientation
                $("#OrientationAlert").hide();
                $("#SampleContent").show();
            }
        }
    } else {
        $("#OrientationAlert").hide();
    }
// ]]></script>

So what exactly does this do? First things first, if you think back to the previous blog post, you'll remember that we had to do some HTML "if" statements to apply the right style sheets to avoid confusing IE. In this scenario, we're doing it differently and only applying the code to the iPad. Line 4 in the code block above scans the user agent string from the browser, looking for "iPad". It then sets the isiPad variable to true if "iPad" is found, or false. We then analyse that variable (at line 5) so that we can do certain things if we're on an iPad, and others if we're not.

In this scenario we're going to hide the sample content in portrait, and show it in landscape. Likewise, if that content is hidden, we're going to show the user the OrientationAlert text so they know there's more available to see if they turn the device. Finally, if they're on a PC (the "not iPad"/else part of the equation) we're just going to hide the user alert since they'll be seeing all of the content.

You'll notice that there's a function in there called "ProcessOrientation" that contains the nuts and bolts of what we're doing. Before we dig into that we need to understand how it gets called. Lines 6 through 9 do a couple things. First things first, we have to call "ProcessOrientation" as soon as the script is loaded so that we determine the initial orientation. We then create a function that calls "ProcessOrientation" and attach it to the window.onorientationchange event. This tells the browser to run "ProcessOrientation" every time the device orientation is changed.

Now onto ProcessOrientation()--this is the function that does the work. For the purposes of this post, I've combined the landscape and portrait modes (0 and 180, 90 and -90), but you could certainly do different things based on each possibility. We then simply use jQuery hide() and show() to either hide the content and show the instruction alert, or hide the instruction alert and show the content.

With this approach, the orientation of the device really can become an integral component to the user interface and navigation. As an example, you could show different list views based on if the device is rotated to the left or to the right.

Another important thing to note is that this solution can be deployed in a number of ways, such as directly including it in the markup of a masterpage, layout, or individual page, or by including with a content editor web part. So for those of you playing in a Tier1 environment where you can't deploy solutions, you can technically roll out a solution like this through the web GUI.