Notes on Mobile
We don’t need no stinking XPages!

With my mobile app complete, I wanted to see if I could start to decouple my UI from Domino and let it serve as just a backend data source. There are a couple reasons why I want to do this, which I’ll get to later, but for now I just want to stick with some more standard techniques.

Even though I’m going to be working with HTML files exclusively, I’m going to store them in my ‘Customers To GO!’ database for simplicity. At some point I would really like to get my design out of Domino Designer, but that will have to wait until later.

The Plan

The plan at the moment comes down to two main ingredients.

With these two things I think I can recreate the COG application with little change to the source data’s design. Remember the key goal here is to keep the UI completely Domino agnostic.

I’m going to walk though this in pretty much the same way I did with the XPages version and work through each page as I go. So the first page I’m going to work with is the customer list. I created a file resource in my database called ‘index.html’ and ‘app.js’. In addition to all the js script imports for JQuery, etc. the interesting part here is the body of my HTML:

<body>
	<div data-role="page" id="main">
		<div data-position="fixed" data-role="header">
			<h1>Customers On the GO!</h1>
		</div>
		<!-- /header -->
		<div data-role="content" class="companyList">
			<ul data-role="listview" data-inset="true" id="companiesContainer"></ul>
		</div>
	</div>
</body>

Much like the XPages version there really isn’t much to see here. To that, I’m going to add a <script> block that will contain my template that JQuery will use to do my replacements:

<script id="companyTemplate" type="text/x-jquery-tmpl">
	<li>	
	<a href="details.html?openfileresource&documentId=${$data['@noteid']}" >
	
	<span class='companyName'>${entrydata[0].text[0]}</span><br/>
	<span class='companyAddress'>${entrydata[2].text[0]}</span><br/>
	{{if entrydata[3].text[0].length}}
	<span class='companyAddress'>${entrydata[3].text[0]}</span><br/>
	{{/if}}
	<span class='companyAddress'>${entrydata[5].text[0]}, ${entrydata[6].text[0]}   ${entrydata[7].text[0]}</span><br/>
	
	</a></li>
</script>

So the way JQuery templates works is that you define a template like above and give it an ID and set the type to “text/x-jquery-tmpl” then inside that you place HTML that contains replacement sequences that some JavaScript will process later with data that you provide. Everything between the ‘{’ and ‘}’ refers to variable in the JSON object we get later. In my case I’m working with viewentry data so it’s the entrydata variable I want to access. Templates are actually powerfull enough that you can even include conditionally rendered parts using if statements or loops using the each statement.

For a more comprehensive tutorial on JQuery Templates check out this page. Or even just the examples in the templates doc.

For now, I’m going to place this script block in the <head> of my page.

The next thing I need is some JavaScript to do the replacements. I’m going to store almost all of my JavaScript in ‘app.js’.  This is what I have for the start:

/*
 * Everything starts here!
 */
$(document).bind("mobileinit", function(){
	$('#main').live('pageshow',function(event, ui){
		loadMainPageData();
	});
});

function loadMainPageData(){
	// Get the list data.
    $.getJSON(
        'http://10.1.1.39/unplugged/rm.nsf/ALLCOMPANIES?readviewentries&outputformat=json', 
            function(data) {
 
               $('#companyTemplate')                  // Select the template. 
               .tmpl(data.viewentry)              // Bind it to the data. 
               .appendTo('#companiesContainer');   // Render the output.
           }
       );
}

The first part is the JQM equivilant of JQuery’s $(document).ready() function. It let’s you bind actions to particular events that JQM raises. In this case, we can bind some init code to the pageshow event for the <DIV> with the id ‘main’. The function we want to call is loadMainPageData()

loadMainPageData() is where the heavy lifting for the template code does it’s work, though it’s pretty simple. First we use JQuery’s getJSON function to make a call to Domino and get my list of companies from CRM database (This is a view that already existed so double bonus!). Using the outputformat=JSON tells Domino to return the view in JSON (imagine that…). The second parameter to the getJSON call is a callback function that receives the JSON Object.

To actually perform the replacement you use the tmpl() call on the script block that contains the template you want to use - in this case the id I want is ‘companyTemplate’. This it’s just a matter of using appendTo() with the id of the DOM object where you want the new HTML to go - in this case ‘companiesContainer’. Then as they say, ‘Bob’s your uncle’!

Dang! OK, so here is the first thing that you will probably run into do this kind of thing with JQM and JQuery. Things don’t always happen in the way you want them to and stylizing lists is one of them. Because the HTML doesn’t actually contain any <li> tags, JQuery doesn’t make any changes to the underlying DOM when it sets up. Once the page is ready, only then do we add the <li> from the AJAX call to Domino. The work around is to tell JQuery to reapply it’s style markup to the list now that we have all the items in place. Simply adding the following call:

$('#companiesContainer').listview('refresh');

after the tmpl() call and all is well.

And that is pretty much it. This didn’t require any changes what so ever to the original applications and I ended up with exactly the result. So far, so good!

  1. notesonmobile posted this
Blog comments powered by Disqus