Building native apps with JavaScript: Titanium — Basic Todo App

This is a continuation of the previous chapter

In the last chapter we ended up with this piece of code. We’ll be expanding it from here to a thing you actually could call an app.

var window = Ti.UI.createWindow({
backgroundColor: "#cccccc",
title: 'Hi there!'
});
var mainWindow = window;
if (Ti.UI.iOS){
mainWindow = Ti.UI.iOS.createNavigationWindow({
window: window
});
}
mainWindow.open();

I’ll be showing iOS screenshots in this tutorial, but keep in mind it’ll work for both iOS and Android and will use native components for each of the platforms. If there are any differences between platforms I’ll highlight it and explain how the different apps work. But you’ll see that.

So what are we going to build?

One of the easiest things to build, and to explain, is to build a Todo app. But there are a lot of ways to build a Todo app. I will guide you to all the different proceses of building a Todo app, starting with the most basic one in this blogpost, and expanding it over the course of time until we have an advance app.

In this blogpost we’ll only focus on making the app work like a todo app. We’ll be showing a list, add options and being able to remove them again.

Make a list

So first thing we’re going to do is make a list in which we can display the different todo items. This list is called a TableView. As any other component you can make it by calling the Ti.UI.createX methods. We’re going to add this section of code before the line mainWindow.open();.

var list = Ti.UI.createTableView();
window.add(list);

So, just creating the TableView and adding it to the Window will take care of everything. Now we can focus on the creation of new todo items. Since we want our app at least to look a bit nice lets change the not so nice #cccccc backgroundColor and change it to #ffffff instead.

As you can see, we’ve now got a window with a nice table and a proper background color. We’re getting closer to our final result, a very basic todo app.

Make an “add” button.

So, we now need to create a way to add a todo item to the list. For a user to be able to actually add an item we’d need a button the user can press. On iOS a button like that is usually added to the top right on the titlebar. On Android we can add it to the actionbar using a menu. This is again one of the differences between iOS and Android. But luckily only the UI is different, all event handling and logic will be cross platform. So lets get started with iOS first.

On iOS we want to position the button on the top right. This spot is, logically, named rightNavButton. Even though it is named a button it accepts any View. So next to a button it could also be a view, label or imageView UI component. We’re going for a button though.

First we’ll check if it is iOS, then create a button and then add it to the rightNavButton property of the window, like this:

if (Ti.UI.iOS){
var addButton = Ti.UI.createButton({
title: 'Add'
});

window.rightNavButton = addButton;
}

This will generate a result like this

Pretty straightforward right? Now this button doesn’t do anything yet, but we’ll get to that once we’ve also added a button to Android. This part is a little bit more complicated.

Android Menu’s require to be added based on a callback function inside the Android activity. So to make this work we’re going to add this code directly below the iOS code:

else {
window.activity.onCreateOptionsMenu = function(e){
var addButton = e.menu.add({
title: "Add",
showAsAction : Ti.Android.SHOW_AS_ACTION_ALWAYS
});
};
}

This will create a button that will always be visible in the menu. When you don’t add “showAsAction” you will see the famous 3 dots in the top right corner which indicates a menu, and you’ll see the single option add in the menu. Our result will look like this:

Now the button doesn’t do anything yet, so lets make it work by adding an eventListener to both buttons, and let them call the same function. By doing this we’re back to centralising our app to cross platform code. I’ve put the created function below the mainWindow.open() line so we can have some organisation in our code. This is our final code:

if (Ti.UI.iOS){
var addButton = Ti.UI.createButton({
title: 'Add'
});
addButton.addEventListener('click', onClickAddButton);

window.rightNavButton = addButton;
} else {
window.activity.onCreateOptionsMenu = function(e){
var addButton = e.menu.add({
title: "Add",
showAsAction : Ti.Android.SHOW_AS_ACTION_ALWAYS
});
addButton.addEventListener('click', onClickAddButton);
};
}
mainWindow.open();
function onClickAddButton(e){
alert('clicked!');
}

The result on Android looks like this (iOS works exactly the same)

So now we have a button that can do something, on both platforms.

Conclusion

Wait what? Conclusion?

Well yeah, this is as far as I will go by explaining “classic” Titanium. Starting in the next blogpost I will talk about the Alloy framework.

But why? We were just getting started!

Well good question, Titanium is a great platform, and “classic” Titanium is the foundation of Titanium. However, you can be much more productive in Alloy. Alloy is the MVC framework of Titanium. But everything is still compiled down to classic. Thats why this tutorial started with the introduction to classic. I will keep referencing to classic in the Alloy tutorials as that is what you end up with in the end, and knowing what is behind is is really powerful.

So what have we learned? You didn’t learn how to add TableViews or Navigation elements. Well you did, but thats not the point. What you’ve learned are some fundamental differences between Android and iOS. The ones we’ve encountered so far are probably two of the biggest differences in the platform, but they can be easily overcome.

What you’ve also learned is how to nest elements and reference them. We’ll get to that much more in depth later.

Patreon

Please support me in writing this series of Tutorials by backing me on Patreon. Not only are you helping me write this, but also you help me run the Community Slack, support me in writing new widgets/modules (and maintain already existing ones) and you can request private support from me and get previews and notifications on next posts!

Hope to see you there, even if just for $1! Thanks already.

Patreon Link: https://www.patreon.com/wraldpyk