I've recently incorporated a VERY simple Sencha Touch application into XBlog, if you visit this blog with a mobile device you will see it in action. The reason for this was because when attempting to read one of my favorite blogs on my Android phone I got really frustrated that it was so small and having to scroll up, down, left and right just to read a short post. This prompted me to look at my blog on my Android and it was even worse! So, we now need a mobile front end for XBlog.
Now for a normal Sencha Touch application seems everyone places their javascript files in a directory called app and within that app.js. The Sencha touch framework is placed in a lib directory and then an index.html file. This actually poses a couple of problems for an XPage application. First, how do you get a visitor to the index.html file when they enter the application with a mobile device? Sure, we could redirect them, but that's not cool and some browsers complain about being redirected. Next issue is if we run this from a javascript file that is not running within the context of an XPages application, how do we get data from our application?
To address both of these issues, there is a component that is not included in the component palette (it may be there it's just I don't know the name of it) which is an <xp:scriptBlock> component. This component allows you to place a client side javascript script on your xpage. This actually fits the bill for the issue of our client side javascript running outside the context of an XPage application by placing our application within the context of an XPage application. And since it's on an XPage, no need to redirect to index.html. All thats left to getting everything working is to include all the other needed javascript and css files as resources to the page. As a bonus we can set the "loaded" property accordingly to only be loaded when someone visits the site with a mobile device for our script block and the included resource definitions.
So let's take a look at the setup here. I've added the sencha framework in WebContent\sencha\lib\ and the only javascript file that I placed in this directory structure is within WebContent\sencha\app\models\ you can also find WebContent\sencha\app\app.js and WebContent\sencha\index.html however these files are basically a formality to traditional sencha touch apps. I've also added a script blog component to a custom control which contains our sencha touch application. I want to veer off course for a second at this point and comment about Sencha Touch in general. As an application framework, the use of Ext makes it very straight forward to program with. Everything is an object and using basic javascript skills it's easy to implement a sencha touch application. The Mobile UI for XBlog only took a few hours to implement. It was getting data and learning how models, stores and proxies work in relationship to sencha touch that took the most time. Once I learned the basic premise of the data store model it was just a matter of creating my own REST service and pointing my data store to that REST service.

Let's take a look at the javascript which is pretty much the entire UI of the XBlog Mobile site:
Ext.regApplication({
name: "XBlogMobile",
defaultTarget: "viewport",
models: ['BlogListModel'],
stores: ['BlogListStore'],
launch: function() {
//This is the data store with proxy to the REST service
Ext.StoreMgr.register(new Ext.data.Store({
storeId: 'BlogListStore',
model: 'BlogListModel',
autoload: true,
proxy: {
type: 'rest',
url: Ext.getHead().dom.baseURI + "/default.xsp?" + xblogMobileRest.extraArgs + "&type=BLOG",
format: 'json'
}
}));
//This is the title bar at the top of the viewport
this.listTitleBar = new Ext.Toolbar({
title: "#{javascript:XBlogUtils.getConfigValue('BlogName',0).toString();}",
items: [{
id: "SenchaBackButton",
text: 'back',
ui: 'back',
handler: function() {
XBlogMobile.viewPort.setActiveItem('blogList', {type: 'slide', direction: 'right'});
var backButton = Ext.getCmp("SenchaBackButton");
if (backButton) {
backButton.hide();
}
}
}]
});
var backButton = Ext.getCmp("SenchaBackButton");
if (backButton) {
backButton.hide();
}
//This is the panel that we navigate to when someone clicks an entry in the blog list
this.postPanel = new Ext.Panel({
id: "postPanel",
scroll: 'vertical',
tpl: "<div class='MobileBlogTitle'>{title}</div><div class='MobileBlogDate'>{createdDate}</div><div class='MobileBlogEntry'>{content}</div>"
});
//This is the list of blog posts
this.listPanel = new Ext.List({
id: 'blogList',
store: 'BlogListStore',
scroll: 'vertical',
itemTpl: "<div class='MobileBlogListItem'><span class='MobileBlogListTitle'>{title}</span><br><span class='MobileBlogListDate'>{createdDate}</span></div>",
onItemDisclosure: function(record, btn, index) {
var backButton = Ext.getCmp("SenchaBackButton");
if (backButton) {
backButton.show();
}
XBlogMobile.postPanel.update(record.data);
XBlogMobile.viewPort.setActiveItem("postPanel");
}
});
//This is our actual viewport panel that holds everything
this.viewPort = new Ext.Panel({
fullscreen: true,
scroll: false,
layout: 'card',
cardSwitchAnimation: 'slide',
dockedItems: [XBlogMobile.listTitleBar],
items: [XBlogMobile.listPanel, XBlogMobile.postPanel]
});
Ext.getStore("BlogListStore").load();
}
});
For the data store I included it here so that I could use EL to make SSJS calls to get some of the more pertinent information easily. Normally the data store would be it's own file. So, this covers almost everything except the data model and REST service. The data model just defines the structure of our data and is a very simple file:
Ext.regModel('BlogListModel', {
fields: [
{name: 'title', type:'string'},
{name: 'createdDate', type: 'string'},
{name: 'content', type: 'string'},
{name: 'unid', type: 'string'}
]
});
I know that all this isn't that complex but I think that's the beauty of Sencha Touch, it makes for very clean, simple code. Plus it's a fun framework to mess with. Now, if you'll notice in the top most code snippet there is a data store which includes a proxy item. The proxy is what tells the store the url to call to get it's data. In this case that url is the url or our REST service along with what we're looking for (i.e. BLOG, FULLARCHIVE or ARCHIVE note only BLOG is currently implemented). I'm sure this will all change in the future to support more data being sent to the browser, but for now simple is good. I would like to make the way data is retrieved to be more lazy and provide some paging in order to navigate all of the blog posts instead of the top 10.
So hopefully this will prompt you to take a look at Sencha Touch for your applications. To me it's a very elegant framework that isn't too difficult to use. The biggest hurdle is learning it, but once you take the plunge it's not very difficult, the hardest part is getting data. As for issues I encountered.... well the only real issue was scrolling (which sadly wasn't fixed in the 0.7.1a release) but the fix was just adding a couple of missing properties to the appropriate sencha components.