API Development

Building an Advanced Transaction UI with Titanium

Building advanced user interfaces in Titanium is pretty easy – once you get the hang of it. In this tutorial, I’m going to walk through how to build an advanced transactional UI – one that might be used for example in an application that captures credit card and needs a signature right on the device. Square is currently a popular company located here in San Francisco that’s doing this type of app. We used their signature screen as an inspiration for this tutorial.

So, let’s first start off with with I call the wrapper view. The wrapper view is the main white box that serves as the main interface area. It has a shadow on the left and right and a drop shadow at the bottom. The main parts of this wrapper view are that it contains the signature, signature line, amount, etc. We start off by creating a basic window and view for the wrapper and the shadow.

var win = Ti.UI.createWindow({  
    backgroundColor:'#ddd'
});

// create our wrapper view.  we offset from the top -2px so that we can eliminate
// the top border from display
var wrapper = Ti.UI.createView({
    width:'95%',
    top:-2,
    height:250,
    borderColor:'#aaa',
    borderWidth:2,
    backgroundColor:'#fff'
});

// we create a simple view that serves as the bottom shadow of the wrapper view
var wrapperShadow = Ti.UI.createView({
    width:'95%',
    height:2,
    backgroundColor:'#bbb',
    top:247
});

win.add(wrapper);
win.add(wrapperShadow);

So, far, we’re just using simple views with some custom properties. Notice, we create the shadow by simply placing the view just below the wrapper and set the height to 2px but make him the same width as the wrapper and with a slightly lighter grey. This will create the shadow effect.

We also create a border with the wrapper view, but we offset his top position from -2 pixels from the parent, which effectively hides the top shadow. This gives a nice effect. Also notice that the wrapper is using a calculated percentage for the width, 95%.

Next, we want to add the buttons along the bottom. I’m using 2 simple pill like images and a fixed close image. The pill images will automatically stretch in Titanium. For the close button image, it’s a fixed size.

Now, add the buttons and customize them:

var doneButton = Ti.UI.createButton({
    backgroundImage:'blue.png',
    title:'Done',
    width:90,
    height:35,
    right:12,
    bottom:10,
    font:{fontFamily:'Arial',fontWeight:'bold',fontSize:14},
    opacity:0
});

var clearButton = Ti.UI.createButton({
    backgroundImage:'clear.png',
    width:26,
    height:27,
    right:20,
    top:10
});

win.add(doneButton);
win.add(clearButton);

var cancelButton = Ti.UI.createButton({
    backgroundImage:'gray.png',
    title:'Cancel',
    width:90,
    height:35,
    left:12,
    bottom:10,
    font:{fontFamily:'Arial',fontWeight:'bold',fontSize:14},
});

win.add(cancelButton);

Notice in my Done button, I make the initial opacity to 0 – effectively hiding it. I do this until the user signs which I’ll explain below.

Now, we’re going to add some text along the bottom for the Terms and Conditions.

var terms = Ti.UI.createLabel({
    text:'I agree that this demo is very very cool.\nCan we get a shout out?',
    textAlign:'center',
    width:'auto',
    height:'auto',
    font:{fontFamily:'Arial',fontSize:12},
    color:'#555',
    shadowColor:"#fff",
    shadowOffset:{x:1,y:1},
    bottom:12
});

win.add(terms);

Notice, we use a slight text shadow on the label.

Now, let’s start the middle wrapper area by drawing the signature line.

// our signature line is simply a 2px view
var sigLine = Ti.UI.createView({
    width:'90%',
    height:2,
    backgroundColor:'#aaa',
    bottom:40
});

A line can simply be created by creating a view at a fixed height (or width if vertical) and a backgroundColor to fill the space. In this case, we simply create a line that’s 90% of the parent container (the wrapper view).

Now, the name below the signature:

var sigName = Ti.UI.createLabel({
    text:'Jeff Haynie',
    textAlign:'center',
    width:'auto',
    height:'auto',
    font:{fontFamily:'Arial',fontWeight:'bold',fontSize:18},
    color:'#999',
    bottom:10
});

Simple enough.

Let’s now add the X next to the signature line, indicating the user should sign on the line.

var thex = Ti.UI.createLabel({
    text:'X',
    textAlign:'center',
    width:'auto',
    height:'auto',
    font:{fontFamily:'Arial',fontSize:24},
    color:'#aaa',
    bottom:45,
    left:20
});

We simply position the X text next to the left of the line.

Let’s add the price and the pay to description up near the top:

var price = Ti.UI.createLabel({
    text:'$9.99',
    width:'auto',
    height:'auto',
    left:25,
    top:8,
    color:'#333',
    font:{fontFamily:'Arial',fontSize:54},
    shadowColor:"#eee",
    shadowOffset:{x:1,y:1}
});
win.add(price);

var payto = Ti.UI.createLabel({
    text:'Pay to: Appcelerator, Inc.',
    width:'auto',
    height:'auto',
    left:28,
    top:70,
    color:'#777',
    font:{fontFamily:'Arial',fontSize:12},
    shadowColor:"#eee",
    shadowOffset:{x:0,y:1}
});
win.add(payto);
wrapper.add(sigLine);
wrapper.add(sigName);
wrapper.add(thex);

The next part is a custom module that I’ve developed using the Module SDK. More details on how to build modules can be found in the Module SDK documentation. We’ll have some specific module tutorials soon. Additionally, we’re going to be launching a Module marketplace really soon, so stay tuned.

Back to my signature, I created a simple module called Paint. It also you to create a simple paint view for simple drawing. Let’s add my custom module code:

var paint = Ti.Paint.createView({
    strokeWidth: 6,
    strokeColor:'#2a81df',
    zIndex:10,
    bottom:0,
    top:30
});
wrapper.add(paint);

The paint view allows me to customize the size of the pen and it’s color. I also place the paint view at zIndex 10 – simply above any of the other views. That way if the user draws over the signature line or any of the others elements, it will be drawn above them.

Now, we can add some simple logic to the application.

clearButton.addEventListener('click',function()
{
    // clear the canvas
    paint.clear();
    doneButton.animate({opacity:0,duration:500});
});

In my new module, I exposed a method to clear the view of the drawing. So, I simply attach a click listener to my button, clear the paint view and hide the Done button with a nice animation.

Now, let’s show the Done button when the user is done signing – or at least after they start the signature. I simply do this once the touchend event is fired on the view – meaning the user at least starting painting and finished.

paint.addEventListener('touchend',function()
{
    doneButton.animate({opacity:1,duration:500});
});

We simply just fade in the Done button with a nice animation on the opacity.

Our done button simply just prints an alert. Trivial:

doneButton.addEventListener('click',function()
{
    alert("Thanks!");
});

Now, let’s open up the window and force our orientation on the window.

win.orientationModes = [ 
    Titanium.UI.LANDSCAPE_RIGHT
];
win.open();

Titanium.UI.orientation = Titanium.UI.LANDSCAPE_RIGHT;

The first line will tell the window which orientations that the window can be rotated to. The last line simply forces the UI device orientation into a specific mode, programmatically. Since we can’t force the user to rotate the device, we can software rotate it for them.

And, that’s about it.

This tutorial demonstrates how you can build fairly advanced user interfaces without much code. It also shows the power of the use of Titanium views to do a lot of graphical work for you. You can always use images for your drawing, but something it’s much easier and faster to simply use customized views.