At the request of a reader this next tutorial will cover Mojo Lists however it will get quite long so I have decided to break it into smaller parts.
Part 1 (This section) will deal with setting up a static list.
Part 2 will show how to use a cookie as a data source.
Part 3 will be some restructuring of the code
Part 4 will show how to use the depot as a data source.
Part 5 will show how to use an Sqlite database as the source.
Source Code will be posted for download after the series is complete.
On our main scene we are going to show a static list of items. This means that we are going to use an array of elements which will never change over the lifetime of the application. The list item data will be specified by us and not fetched from any data source. The main list will give you options to choose from such as using a Cookie, Depot or Sqlite for the data source. When you tap on one of these options another scene will be displayed that will actually load another list. The data that populates these lists will come from the data source that you specified. This should give you the ability to write your own lists using any data source that you see fit.
The very first thing that you need to do is create a new WebOS application and add a new scene to it called main. Now that we have the main scene created we need to alter our stage-controller.js so that it actually pushes the main-scene on startup. Open the file and make the code look like this.
1 2 3 4 5 6 |
function StageAssistant() { } StageAssistant.prototype.setup = function() { Mojo.Controller.stageController.pushScene(“main”); } |
With that in place it’s time to actually start working on the view file. Let’s open the main-scene.html file and add the following code to it.
1 2 3 |
<div id=“feedTitle” class=“palm-header center”> List Data Sources </div> <div class=“palm-header-spacer”></div> <div id=“mainScene” class=“mainScene”> <div x-mojo-element=“List” id=“mainListWgt”></div> </div> |
This is pretty basic HTML for the most part. The only item that is really of concern here is the div that specifies the x-mojo-element="List". This tells the Mojo Framework that you wish to have a list reside in that position in the view. Now that we have the view in place and Mojo knows where we want our list to display it’s time to actually start working on our list. We will first need to create 2 template files. We will put these files in the same directory as the main-scene.html file. We will need one template for our list and then another template for each row in our list. We will start off with the List template so create a file called mainListTemplate.html and add the following code to it.
1 |
<div class=“palm-list”>#{-listElements}</div> |
All this file really does is create a div for our listElements to be placed in. Think of a listElement as a row in the list. You will notice one thing above that might look a little out of place and that is the use of the – (dash) in the template code. Since each of our rows will contain HTML we need a way to tell Mojo not to escape this HTML so that our list will render properly. Whenever you are using a value in a template with #{value} Mojo will escape the HTML and things will not look good. If you add the dash as in #{-value} this specifically tells Mojo that we do not want the HTML escaped.
Let’s continue on and create the list row template. Create another file called mainRowTemplate.html. Add the following contents.
1 2 3 4 5 |
<div class=“palm-row” x-mojo-touch-feedback=“delayed”> <div class=“palm-row-wrapper”> <div id=“itemTitle” class=“title truncating-text”>#{title}</div> </div> </div> |
This file has a little bit more code than the last but it is all trivial. First we create a div and use the class palm-row which is a CSS class defined in the Mojo Framework. We are just applying some Palm default styling here. You will also see the x-mojo-touch-feedback="delayed". This tells the framework to have a short delay when a user taps on the item. You can see this once you have everything setup and test the list. We continue on to create another div and assign it the palm-row-wrapper class. This is just a wrapper div that takes care of the look of the list row. Inside that div is the actual div that you want to be concerned with. You can notice that we are using the truncating-text class for this element. All this does is truncate the text if it is too long to fit on the screen. Rather than seeing the list look bad if the text is too long the style will truncate it at that perfect length as to not disturb how the list looks. You might also notice that we are using #{title}. You might wonder why we are not telling the framework to escape the HTML of the title however we do not want someone to inadvertently add HTML markup to the title and be able to change how things look in our list. Letting Mojo escape the HTML will not add any formatting that we did not intend to have in place.
We are almost completed with our static list. The last thing we need to do is actually put the JavaScript code in our assistant so that our list becomes something we can interact with. We are going to open up the main-assistant file and make it look like the code below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
function MainAssistant() { this.listItems = [ { title: “Cookie” }, { title: “Depot” }, { title: “SqLite” } ]; } MainAssistant.prototype.setup = function() { this.controller.setupWidget(“mainListWgt”, { itemTemplate: “main/mainRowTemplate”, listTemplate: “main/mainListTemplate”, swipeToDelete: false, renderLimit: 40, reorderable: false }, { items: this.listItems } ); this.mainListHandler = this.loadDataSource.bindAsEventListener(this); this.controller.listen(“mainListWgt”, Mojo.Event.listTap, this.mainListHandler); } MainAssistant.prototype.loadDataSource = function(event) { Mojo.Controller.stageController.pushScene( this.listItems[event.index].title.toLowerCase() ); } MainAssistant.prototype.activate = function(event) { } MainAssistant.prototype.deactivate = function(event) { } MainAssistant.prototype.cleanup = function(event) { } |
If you were to build your application right now it would load up the main scene and show you the static list. It is not very pretty it is just a list that gives you the ability to choose a storage mechanism. You can see in the MainAssistant() constructor I am initializing a variable called this.listItems which is an array that holds objects. The objects are really basic as they only contain a title property however you could put any information in there. If for instance you wanted a short description below the title of the list element you could add a description: “this is a brief description” to the objects and then put the code in place on the view for it to be displayed. The objects are really just being used as a static storage mechanism for this main list. When you look into the setup method you are going to see a few things that might seem foreign to you. First you will sett a call to this.controller.setupWidget() This is a method that we call which will actually set-up our list widget for use. You have to pass in 3 parameters to this method. First the ID of the element in the view, second the attributes which describe our widget. For instance you will notice that we had to specify the list templates here. The last item you have to provide is the model and that is the data that will populate the widget.
The last two lines of code you see in the setup method are the lines that actually set-up listening for the event handler. The first line does the actual binding and sets that to a property of the MainAssistant. The second line makes the call to the controller to setup the listener for the event we want. We want something to be done when a user taps a list item so we are using the Mojo.Event.listTap event. This method is very much like the setupWidget method as it also takes 3 arguments. First the ID of the element in the HTML view file then the event we wish to listen for. Finally you specify your method that you want called when the event is captured. In our case we are going to call the method loadDataSource every-time a list item is tapped.
When the loadDataSource method is called the tap event is passed into it. This is useful for finding out which list item was tapped. We are using an array remember so when you tap an item the element index is passed into our method. We simply reference the scene that we want pushed with the this.listItems[event.index].title.toLowerCase(). This is just fetching the proper item and converting the title to lowercase. We need to call our scene by lowercase. If you were to tap the Cookie item in the list then this code pushes the scene to cookie-scene.
There are just a few more things we need to do. If you recall back in the setup method of the main-assistant we created a listener. Now we need to clean up after that listener. When the application is closed we want to stop listening for events. If you do not clean up after your listeners your application will end up having memory leaks. Luckily it is very easy to clean up after yourself. Go back to your main-assistant file and add the following code to your cleanup method.
1 2 3 4 |
MainAssistant.prototype.cleanup = function(event) { Mojo.Event.stopListening(this.controller.get(“mainListWgt”), Mojo.Event.listTap, this.mainListHandler); } |
The final bit that we need to do before we complete Part 1 is actually create the other scenes that we will need for each storage mechanism. Create 3 more scenes named cookie, depot and sqlite. Once you have done that you can feel free to build the application and test it out. Tapping on a list item will show the default template. In part 2 we will work on the ability to use a cookie as a storage mechanism.