jQuery Mobile and SharePoint

As an experiment, I decided to explore the use of jQuery mobile with SharePoint. My goal is to simply expose company news for as many mobile devices as possible in a single location. Like many organizations, our consulting firm delivers news internally via our intranet portal (based on SharePoint) and through public press releases available for anyone in the world.

Scenario

Our organization has grown and we have several new employees. There is a need to help these new employees find a central place to obtain news. We also have existing employees that have expressed a desire to know more about what other teams are doing, since we all like to celebrate the successes of our company. Much of this information has been centralized within our SharePoint portal, but this is not always a convenient place to view since many of our consultants are highly mobile and may only have a few minutes to review email and news between flights or meetings with clients. However, all of our consultants are making use of some type of smartphone, so if there were a way to present this information on those devices a quick update can happen almost anywhere. Even though our consultants use smartphones, we’ve found that our smartphone preference is as diverse as our skillsets, so developing a single native application for each platform (iOS, Android, Windows Phone, etc.) would just be too expensive.

Assumptions

It is assumed that your SharePoint environment is available outside any corporate firewalls and can be navigated directly from your mobile device. I am also assuming that you have an understanding of how to use the technologies described in this document and I have provided links at the end of this post to these tools where you can discover more information. I will provide brief description for jQuery mobile, but I refer you to their documentation for full details on how to use the framework.

Goals

The goals for this project are quite simple, to centralize news and provide it on as many devices as possible. We also want to reuse as much of our existing skill sets as possible – we have a lot of experience working with web technologies including HTML and SharePoint.

Technologies Available

The first step is to identify the available ways to retrieve our news feeds. SharePoint can provide our feeds via RSS or we can make use of the SPServices library by Marc Anderson to work with SharePoint’s web services.

The most difficult portion of the project will be retrieving external newsfeeds via RSS. This is because I will have to make cross-domain calls — something that is considered a security risk. For this, Google provides a way for us to use their Feed API and return our feed as JSON.

Finally to support mobile devices, we will make use of the jQuery Mobile plug-in. This plug-in is still in beta, but it looks very promising and supports a very large number of devices.

Solution

The final solution is made up of four HTML pages hosted in a SharePoint document library and a shared JavaScript file referenced on all of the pages.

default.htm

Image for: default.htm

First, the entry point into the solution is default.htm and begins the end-user experience. Using HTML pages instead of ASPX pages allows full control of the markup produced by the solution. I did some initial experiments with data view web parts hosted on ASPX pages, but the data view web parts prefers to be wrapped in a form element. This would occasionally break the markup required for jQuery mobile. It also insured page-to-page navigation would require non-ajax navigation.

This page acts as a menu for each of the various news areas, allowing the employee the choice to review each section of content.

<!DOCTYPE html>
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Tribridge News</title>
<link rel="stylesheet" type="text/css" href="../../Scripts/jquerymobile/jquery.mobile-1.0b2.min.css">
<link rel="stylesheet" type="text/css" href="news.css">
<script type="text/javascript" src="https://www.google.com/jsapi?key=<PROVIDE YOUR GOOGLE API KEY>"></script>
<script type="text/javascript">
google.load("feeds", "1");
</script>
<script type="text/javascript" src="../../Scripts/jquery/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="../../Scripts/jquery.SPServices-0.6.2.min.js"></script>
<script type="text/javascript" src="../../Scripts/jquerymobile/jquery.mobile-1.0b2.min.js"></script>
<script type="text/javascript" src="jquery.jgfeed-min.js"></script>
<script type="text/javascript" src="news.js"></script>
</head>

<body>

<div data-role="page" id="Main" class="tribridge-page">
	<div data-role="header" class="tribridge-header">
		<h1>News</h1>
	</div>
	<div data-role="content" class="tribridge-content">
		<div class="page-logo">
		</div>
		<ul data-role="listview" data-inset="true" class="tribridge-listview" data-dividertheme="a">
			<li data-role="list-divider">Internal News</li>
			<li><a href="golive.htm">Go Live Announcements</a></li>
			<li><a href="tribridgenews.htm">Tribridge News</a></li>
			<li data-role="list-divider">Public News</li>
			<li><a href="public.htm">Press Releases</a></li>
		</ul>
	</div>
	<div data-role="footer" class="tribridge-footer"><h1>&copy;2011 Tribridge</h1></div>
</div>

</body>

</html>

jQuery Mobile makes use of specific markup for a page. This is usually an external div tag with several internal div tags for headers, footer, content and navigational elements. According to the documentation, you can also use HTML 5 tags such as header, footer, etc.

jQuery Mobile also makes use of attributes to help the framework know what to do with each element. These attributes are outlined in the documentation for the framework, but they all begin with data-. The final markup of this page is very clean and remains very simple so the employee can very clearly see the available options.

news.js

Image for: news.js

Next, because jQuery mobile makes use of ajax for default navigation, any script located on a secondary page will not execute, however, jQuery mobile does handle this by providing a few new events. In a typical jQuery scenario, you will make use of $(document).ready(…) to initialize your functions. This will change in jQuery mobile to $(“#PageID”).live(“pagecreate”,function (event) {…}). Once you get used to this, you are pretty much dealing with jQuery syntax.

I have three pages where content will be dynamically retrieved and placed into the page, so I need to create three page creation events in the jQuery Mobile framework.

$("#GoLiveNews").live("pagecreate",function (event) {
	loadGoLiveNews();
});

$("#PublicNews").live("pagecreate",function (event) {
	loadPublicNews();
});

$("#TribridgeNews").live("pagecreate",function (event) {
	loadTribridgeNews();
});

You can see here that I’m executing different functions depending upon which page is loaded. Each individual HTML page has a jQuery page with the cooresponding ID indicated in the jQuery selector.

Both loadGoLiveNews and loadPublicNews are making use of SPServices to retrieve the data from SharePoint. Because these pages are hosted in SharePoint, the employee is already authenticated so there are no issues with SPServices (as long as you are working within the same domain).

function loadGoLiveNews() {
	$().SPServices({
		operation: "GetListItems",
		CAMLQuery: "<Query>...</Query>",
		CAMLViewFields: "<ViewFields>...</ViewFields>",
		listName: "Pages",
		CAMLRowLimit: 10,
		webURL: "https://...",
		completefunc: function (xData, Status) {
			if(Status == "success") {
				$(xData.responseXML).find("[nodeName='z:row']").each(function () {
					html = "<li><a href=\"#\"><h2>" + $(this).attr("ows_Title") + "</h2><p>" + $(this).attr("ows_...") + "</p></a></li>";
					$("#NewsItems").append(html);
				});
				$("#NewsItems").listview("refresh")
			}
		}
	});
}

There are a few things to notice concerning the SPServices call, mainly as it relates to jQuery mobile. Since I am attaching new items to an existing list view, I will have to refresh the list view after all of the new items are added, ($(“#NewsItems”).listview(“refresh”). This notifies the jQuery mobile framework to work its magic on the new html markup added to the DOM.

Remember, the public news poses a different issue because it is hosted on a site outside of SharePoint. Because of this, in order to retrieve the RSS feed, I would have to make a cross-domain call. This is frowned on heavily in JavaScript since it is considered a security risk. This is where I make use of Google’s Feed API.

In the default.htm page, there is a call to Google’s API:

<script type="text/javascript" src="https://www.google.com/jsapi?key=<PROVIDE YOUR GOOGLE API KEY>"></script>
<script type="text/javascript">
google.load("feeds", "1");
</script>

This will insure the Feed API is ready to use when it is called by the page being loaded. The Feed API returns the RSS feed as JSON, so I can make use of this easily to generate my list of news.

function loadPublicNews() {
	$.jGFeed("http://www.tribridge.com/News.rss.ashx",
	function (feeds) {
		if(!feeds){
			alert("Unable to load news...");
		}
		for(var i=0; i<feeds.entries.length; i++){
			var entry = feeds.entries[i];
			html = "<li><a href=\"" + entry.link + "\" rel=\"external\"><h2>" + entry.title + "</h2><p>" + entry.author + "</p></a></li>";
			$("#NewsItems").append(html);
		}
		$("#NewsItems").listview("refresh");
	},50);
}

Notice that the HTML being generated in the function has the rel attribute set to external. This tells the jQuery Mobile Framework to break out of the AJAX navigation. Since I am sending the employees to the official site, there is no need to keep them in my mobile application.

golives.htm, tribridgenews.htm and publicnews.htm

Image for: golives.htm, tribridgenews.htm and publicnews.htm

Apart from unique ID’s for each jQuery Mobile Page, these pages are identical.

<!DOCTYPE html>
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Tribridge News</title>
<link rel="stylesheet" type="text/css" href="../../Scripts/jquerymobile/jquery.mobile-1.0b2.min.css">
<link rel="stylesheet" type="text/css" href="news.css">
<script type="text/javascript" src="https://www.google.com/jsapi?key=<YOUR GOOGLE API KEY>"></script>
<script type="text/javascript">
google.load("feeds", "1");
</script>
<script type="text/javascript" src="../../Scripts/jquery/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="../../Scripts/jquery.SPServices-0.6.2.min.js"></script>
<script type="text/javascript" src="../../Scripts/jquerymobile/jquery.mobile-1.0b2.min.js"></script>
<script type="text/javascript" src="jquery.jgfeed-min.js"></script>
<script type="text/javascript" src="news.js"></script>
</head>

<body>
<div data-role="page" class="tribridge-page" id="PublicNews">
	<div data-role="header" class="tribridge-header">
		<a href="default.htm" data-role="button" data-inline="true" data-icon="back" data-theme="c" data-direction="reverse">Main</a>
		<h1>Public News</h1>
	</div>
	<div class="tribridge-content" data-role="content">
		<div class="page-logo"></div>
		<ul data-role="listview" class="tribridge-listview" id="NewsItems" data-inset="true">
		</ul>
	</div>
	<div class="tribridge-footer" data-role="footer">
		<h1>&copy;2011 Tribridge</h1>
	</div>
</div>

</body>

</html>

Notice that this page also has all of the same script references as default.htm. This will insure that if this page is navigated to directly, it will still execute as expected. The final result appears as follows:

I hope this article was informative and helps you find business areas where you can leverage SharePoint data on mobile platforms. I am eagerly awaiting the non-beta release of this framework.

I don’t see jQuery Mobile being the best way to present your entire SharePoint environment to an employee, but this example should demonstrate there may business scenarios where a solution similar to this would be beneficial — perhaps things as simple as sharing team contacts to as complex as a issue logging system used by service technicians deployed to the field.

If you develop something using jQuery mobile and SharePoint, I would love to hear about it!

Links

  1. jQuery 1.6.2
  2. jQuery Mobile 1.0 Beta 2
  3. SPServices 0.6.2
  4. Google Feed API
  5. Sign-up for a Google API Key

26 thoughts on “jQuery Mobile and SharePoint

Image for: 26 thoughts on “jQuery Mobile and SharePoint”
  1. Hi! I have a question. Is there a way for me to use this jQuery solution for publishing news, if I want the news only to be available to registered portal users? Meaning, what if I want to authenticate the users?

    I notice that this post says how to create custom RSS feeds using CQWP, but I don’t know how to perform authentication for the mobile devices. I’ve been using Harmon.ie for SharePoint on mobile because it offers security and authentication, but it’s limited in how it can be extended.

    1. Nice find on that post on improving RSS feeds using the CQWP! Thank you for sharing it!

      I cannot speak to the specifics of every environment but I can tell you that if you are working to design a mobile strategy for SharePoint, authentication has to be a consideration. There are third party providers, like Harmon.ie, that can help get you further down the path. Another third party provider is mobile entree (http://www.mobileentree.com/Pages/default.aspx). I currently have a client that is handling authentication via the development of a native mobile application. Other clients are okay with forcing authentication through something like Microsoft TMG.

      When this solution was first designed, it was placed on an already established SharePoint 2010 extranet portal. Authentication for the portal was already being handled via Microsoft TMG and mobile devices could already authenticate, they just had a sub-par experience. The goal of the exercise here was to prove out the possibility of delivering improved mobile views in SharePoint 2010 using an emerging framework, and it was successful for the specific scenario mentioned here.

  2. I’m guessing that you are using SharePoint 2007 here and that’s why you opted for SPServices, as it is likely your only option in such an environment. We recently upgraded to SP 2010. And I am having some issues with jQuery Mobile 1.2.0 and SP 2010. I am using the $(‘#pageID’).live() method, but, for some reason the $.mobile.changePage() is going ahead and happening before all of my SP data is loaded into the DOM elements. The user would click a link lets say that goes to itemDetails.aspx that would do the following:
    1. $.mobile.loadPage(‘itemDetails.aspx’);
    2. $(‘#itemDetailsPage’).live(‘pageinit/pagebeforecreate’ , function () {
    // insert SP stuff into DOM elements using say:
    $(‘#TitleElementID’).html(listItemObject.get_item(‘Title’));
    });
    3. $.mobile.changePage(‘itemDetails.aspx’ , { transition : ‘slide’ });

    Logically, this should: 1. Insert the requested page into the DOM AJAXically, 2. Add the content to the inserted page , 3. Then, change the page.

    But, what happens in actuality is: 1. page is changed, then the loading message disappears, then the content is loaded into the page.

    Any tips would be highly appreciated!

    Thanks in Advance!
    -Torrance Miller

    1. $(‘#itemDetailsPage’).live(‘pageinit/pagebeforecreate’ , function () {
      // insert SP stuff into DOM elements using say:
      $(‘#TitleElementID’).html(listItemObject.get_item(‘Title’));
      $.mobile.changePage(‘itemDetails.aspx’ , { transition : ‘slide’ });
      });

      And you are sorted.

      1. so, what you are saying is that the problem occurs when I call the loadPage() method. Is it not necessary? further, I found that the way I actually wrote my code is a bit silly, in that, I have the binding to the ‘pageinit’ event inside of my SP query success function. Time for a bit of a re-write. 😛

    2. Torrance,

      Yes, when the page was originally written it was under SharePoint 2007. After the environment upgraded to 2010, I do not remember having to rework the solution for items to work. However, you may notice that I used HTML pages instead of ASPX pages so my solution would run as a pure JavaScript solution. I haven’t had time to revisit working with jQuery mobile in the last few months, but from what I remember there should be a callback or an event you can handle for the change page method. This is probably where you want to put your code to load the contents of the page. That’s where I would start if you are dynamically populating data on the secondary pages.

  3. Hi Chris,

    This is great post. I am attempting to do something similar. However I have a few challenges.

    1) SharePoint environment is published online via reverse proxy using TMG over HTTPS and uses forms based authentication.

    2) Mobile site needs to be operational offline.

    Appreciate some advice on how to tackle this.

  4. Nice Article.
    Would you happen to know how to add a custom image for the homepage icon of the web appplication? I have a sharepoint site which is customized for mobile using jquery mobile. So we have this option in ipad to “Add to home screen”. I want to be able to set this image. I came accross loads of articles saying place the image in the root directory of your application and add a link to it. Home directory for a sharepoint site?

    1. If Im right your idea is to have an icon for the Application when you Add to bookmark. Its as easy as adding this meta tag to all your pages in the head section

      I would assume a Favicon would be the default way other mobile browsers would impliment it.

  5. Hi! Thanks for sharing! Btw, how did you enable html inside SharePoint. When I try to open to open defautl.html it is just downloaded, not rendered (the same in all browsers). The aspx is rendered with no problems.

    1. You may have to check with your administrator to see if Strict browser handling is enabled. If it is, that will explain why HTML gets pushed to the browser as an attachment.

    1. When I first explored jQuery Mobile, it was in beta. Now it is in version 1, so it has become a much more viable option.

      Looking at jQuery Touch it appears to be focused on iPhone and Android (webkit based browsers). I would be interested to know if it downgrades gracefully for other mobile browsers that are not based on webkit.

      1. We latter caned the frameworks in abid to get the site more crossbrowser. The spec later introduced devices like “Symbian” . If you are looking to have the feeds and DOM manipulation working perfectly and fast the best approach would be to use Frameworks a bit sparingly. Didnt use the jQuery feed plugin and went with the default Google feed approach and a hell lot of yahoopipes for the search functionality we implimented.

        jQTouch is lightweight “bullet” fast actually lightnigh fast 🙂 . I love the syntax of jQTouch as compared to jQMobile although I know the whole “data-id” etc approach makes Javascript selectors run faster etc.

        For symbian to behave we had to do less DOM manipulation and instead of your approach of iterating and inserting the elements in a loop I took the more optimised approach of building the string and inserting everything once into the page with document.innerHTML(). I only used jQuery for complex/tricky feed traversals and did everything the default plain JS way of document.getElementByTagName() etc. Its onbviously the faster approach when dealing with such low thinking devices.

        The fully working site is now on http://m.citadel.co.za as you will see in the source there are quite allot of jQuery syntacticall approaches that were later commented out.

  6. I’m trying to build a proof of concept based on your code, but unfortunately I can’t find any publicly accessible sp2010 web services. I can’t mess with our production code, and my test environment is sandboxed pretty hard. Just for demo purposes does anyone know of a service I could access?

    1. You most likely wont find much luck with that approach (Cross Domain issues at most). The best approach is using a feed from a public facing site.

Leave a comment