Get $500+ of the best After Effects files, video templates and music for only $20!
Build a Titanium Mobile Pizza Ordering App: Crust Selection

Build a Titanium Mobile Pizza Ordering App: Crust Selection

Tutorial Details
  • Technology: Titanium Mobile SDK
  • Difficulty: Intermediate
  • Estimated Completion Time: 30 Minutes
This entry is part 1 of 4 in the series Build a Titanium Mobile Pizza Ordering App

In this multi-part tutorial series, I’ll be teaching you how to build a Titanium Mobile app from start to finish. Specifically, you’ll learn how to build a Pizza Shop app that will allow customers to order a custom pizza on the go. In this tutorial, I will demonstrate how to setup the project and create a “Crust Selection” screen.

Step 1: Create a New Project

Open up Titanium and create a new mobile project. Now is a good time to go ahead and download the zip file attached to this post as well. The zip file attached to this post contains a subfolder called “images”. Once you have created your empty project, place the “images” folder in your new project’s “resources” folder. While inside the “resources” folder, go ahead and create a new subfolder called “main_windows” as well as a subfolder called “includes”.


Step 2: Edit App.js

Browse to the Resources/app.js file. There is a lot of stuff in this file already that we do not need. Go ahead and remove everything and replace it with the following:

Titanium.UI.setBackgroundColor('#8C0221');

//-- Create our main window that will contain all our sub windows
var main = Ti.UI.createWindow({
    url:'main_windows/main.js',
    height:Ti.Platform.displayCaps.platformHeight,
    width:Ti.Platform.displayCaps.platformWidth,
    fullscreen:true,
    navBarHidden:true
});
main.open();

What we did here is set our background color, made a new window called “main”, and then opened it. Main will hold all of our sub windows like crusts and toppings.

Notice the URL property on the window. In the Resources folder, make a new folder called “main_windows” if you haven’t already and a new JS file called main.js. The URL property tells the compiler to use main.js as our window. If you skip this part, Titanium will throw an ugly red error in the emulator.


Step 3: Adding a Background and a Clock

If you haven’t already made a main.js file and saved it in the main_windows folder, do so now. Open main.js and add the following:

var win = Ti.UI.currentWindow;

//-- Create the sub windows
var crusts = Ti.UI.createWindow();
var toppings = Ti.UI.createWindow();
var details = Ti.UI.createWindow();

//-- We set the background here since this wont change
win.backgroundImage = '../images/bg_main.png';

//-- Include our clock
Ti.include('../includes/clock.js');

If you haven’t created an “includes” folder in the resources folder, do so now. Next, create a new JS file called clock.js. Save it to the “includes” folder and add the following:

var time = Ti.UI.createLabel({
    text:'',
    font:{
        fontFamily:'Verdana',
        fontWeight:'bold',
        fontSize:14
    },
    color:'#fff',
    shadowColor:'#333',
    shadowOffset:{x:1,y:1},
    textAlign:'right',
    width:Ti.Platform.displayCaps.platformWidth,
    height:20,
    top:45,
    left:-13
});

function getFormattedTime()
{
    var amPM = '';
    var d = new Date();
    var currentHour = d.getHours();

    if (currentHour < 12)
    {
        amPM = 'AM';
    }
    else
    {
        amPM = 'PM';
    }

    if (currentHour == 0)
    {
        currentHour = 12;
    }

    if (currentHour > 12)
    {
        currentHour = currentHour - 12;
    }

    var currentMinute = d.getMinutes();
    currentMinute = currentMinute + '';

    if (currentMinute.length == 1)
    {
         currentMinute = '0' + currentMinute;
    }
    time.text = currentHour + ':' + currentMinute + ' ' + amPM;
}
var clockInterval = setInterval(getFormattedTime,5000);
getFormattedTime();
win.add(time);

So what we did is create 3 sub windows, set our background and included a clock that updates every 5 seconds. The reason for the clock is our application is set to fullscreen mode, so the default device status bar and time will not be displayed. Go ahead and compile. Your screen should look like the below image:


Step 4: Creating and Opening the Crusts Window

Create a new JS file called crusts.js and save it in the main_windows folder. You can leave it blank for now. Go back to main.js. We need to add a method that opens our crusts window, so add the following to main.js

function openCrust(e)
{
    crusts.url = 'crusts.js';
    crusts.open();
}
openCrust({});

To explain the above: we made a method called openCrust(), we set the url property on our crusts window to “crusts.js”, and then we opened it. The reason we are passing an empty object is because later in this tutorial series, we will actually be passing data to this method. You don’t need to compile just yet as you will see no visible change.


Step 5: Editing the crusts.js File

This file will contain a scroll view that allows the user to swipe through the various crusts offered by our pizza shop. We will also add a next button that will take the user to the toppings window:

var win = Ti.UI.currentWindow;

//-- Our crust views
var handMade = Ti.UI.createView({width:216,height:156,backgroundImage:'../images/crust/hand.png'});
var natural = Ti.UI.createView({width:216,height:156,backgroundImage:'../images/crust/natural.png'});
var panCrust = Ti.UI.createView({width:216,height:156,backgroundImage:'../images/crust/pan.png'});
var stuffedCrust = Ti.UI.createView({width:216,height:156,backgroundImage:'../images/crust/stuffedCrust.png'});
var thinNCrispy = Ti.UI.createView({width:216,height:156,backgroundImage:'../images/crust/thinNcrispy.png'});
var returnCrust;

//-- Crust reference
var crusts = [
    {title:'Hand Made',path:'../images/crust/hand.png'},
    {title:'Natural',path:'../images/crust/natural.png'},
    {title:'Pan Crust',path:'../images/crust/pan.png'},
    {title:'Stuffed Crust',path:'../images/crust/stuffedCrust.png'},
    {title:'Thin N Crispy Crust',path:'../images/crust/thinNcrispy.png'}
];

//-- Our scroll view that contains our crust views
var scrollView = Ti.UI.createScrollableView({
    views:[handMade,natural,panCrust,stuffedCrust,thinNCrispy],
    showPagingControl:true,
    clipViews:false,
        top:180,
        left:30,
        right:30,
        height:180,
        opacity:0
});

//-- Crust title
var crustTitle = Ti.UI.createLabel({
    text:'1. Choose a crust',
        font:{
            fontFamily:'Verdana',
            fontWeight:'bold',
            fontSize:24
        },
        color:'#A90329',
        shadowColor:'#333',
        shadowOffset:{x:1,y:1},
        textAlign:'left',
        width:Ti.Platform.displayCaps.platformWidth,
        height:58,
        left:10
});

//-- Crust title background
var crustTitleView = Ti.UI.createView({
        width:328,
        height:58,
        backgroundImage:'../images/crustHeaderBg.png',
        top:100,
        left:-6,
        opacity:0
});
crustTitleView.add(crustTitle);

//-- Crust type label
var crustType = Ti.UI.createLabel({
        text:'Hand Made',
        font:{
            fontFamily:'Verdana',
            fontWeight:'bold',
            fontSize:16
        },
        color:'#fff',
        shadowColor:'#333',
        shadowOffset:{x:1,y:1},
        textAlign:'center',
        width:Ti.Platform.displayCaps.platformWidth,
        height:20,
        top:170,
        opacity:0
});

//-- Next Button
var next = Ti.UI.createButton({
        width:137,
        height:75,
        backgroundImage:'../images/toppings_next.png',
        top:385,
        opacity:0
});

//-- If android OS, use the image property instead of backgroundImage (Ti SDK bug)
if (Ti.Platform.osname == 'android')
{
    next.image = '../images/toppings_next.png';
}

next.addEventListener('click',function(e){
    Ti.App.fireEvent('toppings',{
        crust:crusts[scrollView.currentPage].title,
        path:crusts[scrollView.currentPage].path
    });
});

win.add(scrollView);
win.add(crustTitleView);
win.add(crustType);
win.add(next);

//-- Fade the scrollview in
scrollView.animate({
    opacity:1,
    duration:500
});

//-- Fade the crust title in
crustTitleView.animate({
    opacity:1,
    duration:500
});

crustType.animate({
    opacity:1,
    duration:500
});

//-- Fade the next button in
next.animate({
    opacity:1,
    duration:500
});

//-- Changes the crust type label text when the user scrolls
scrollView.addEventListener('scroll',function(){
    crustType.text = crusts[scrollView.currentPage].title;
});

So we created our crust views, a scroll view, and added the crust views to the scroll view. We also created a custom title and a next button. Go ahead and compile. Your app should now look like this and have the swiping functionality. As you swipe, you will notice the title above the pizza image will change to whatever crust you are on. That is thanks to the “scroll” event we added to our scroll view.


Conclusion

In part 1 of this series, we created our main window to contain our sub windows. We created an openCrust method that will evolve through this series of tutorials. It is pretty basic right now. We created our first essential screen, the crusts window. This allows the user to swipe through the crusts we offer. The next, or toppings, button is firing a custom event in the background. In the next part of this tutorial, we will look back to our main.js file and listen for the custom event that will allow us to start adding toppings to our pizza!

Series NavigationBuild a Titanium Mobile Pizza Ordering App: Topping Selection»

Ronnie Swietek is rondog on Activeden
Add Comment

Discussion 26 Comments

  1. Cesar Estrada says:

    Great tutorial!!!!

    Can’t wait to try it.

  2. Lucas says:

    This makes me hungry for pizza :)

    Nice tutorial.

  3. curtisaallen says:

    Nice Tuts. Keep them coming.

  4. kuhel says:

    when I load the source of this tutuorial to Titanium and try to run it, there was this error

    [ERROR] Error: Traceback (most recent call last):
    File “/Library/Application Support/Titanium/mobilesdk/osx/1.5.1/iphone/builder.py”, line 1003, in main
    execute_xcode(“iphonesimulator%s” % iphone_version,["GCC_PREPROCESSOR_DEFINITIONS=__LOG__ID__=%s DEPLOYTYPE=development TI_DEVELOPMENT=1 DEBUG=1 TI_VERSION=%s" % (log_id,sdk_version)],False)
    File “/Library/Application Support/Titanium/mobilesdk/osx/1.5.1/iphone/builder.py”, line 925, in execute_xcode
    output = run.run(args,False,False,o)
    File “/Library/Application Support/Titanium/mobilesdk/osx/1.5.1/iphone/run.py”, line 31, in run
    sys.exit(rc)
    SystemExit: 1

    how can I solve this problem?

    • Author

      I would go into the build/iphone/ folder and delete the build folder. If that doesn’t work, you can try and do a touch on the tiapp.xml file. I’ve gotten that error myself before. You can also make a new project and then just copy the resources folder to the new project.

  5. Pat says:

    Thanks! Looking forward to the next in the series.

  6. Great tut! Glad to see Titanium get some more attention on this site.

  7. appleorange says:

    I have problem when im running with Android SDK… it cannot run in the emulator.. somebody can help.. thanks.

  8. Author

    Thanks for all the feedback guys! @appleorage, I did my best to support the android SDK. Titanium mobile is still pretty buggy when it comes to developing for android. Right now the SDK is at 1.5.1. They are releasing SDK 1.6 very soon which is a HUGE update to the android API. As for it not running at all, it ran fine on my android emulator. Be sure you are using Android 2.2 APIs. The only issues I ran into were background images not showing up and even then I got 90% of them to work.

    • mrgoatee says:

      In Android, the background image behind the title isn’t showing up, and so the red text blends in with the background. I added another conditional statement below where the crust title was defined:

      if (Ti.Platform.osname == ‘android’)
      {
      crustTitle.color = ‘#FFFF99′;
      }

      That way, at least you can see the title.

  9. appleorange says:

    Thanks Ronnie. Now i can run this app in my android SDK… nice

  10. Sesli says:

    i am getting

    G:\AndroApp\AppTest\build\android\gen\com\mybilet\apptest\ApptestApplication.java:33: package ti.modules.titanium.xml does not exist
    [ERROR] modules.add(new ti.modules.titanium.xml.XMLModule(context));
    [ERROR] ^
    [ERROR] G:\AndroApp\AppTest\build\android\gen\com\mybilet\apptest\ApptestApplication.java:35: package ti.modules.titanium.network does not exist
    [ERROR] modules.add(new ti.modules.titanium.network.NetworkModule(context));
    [ERROR] ^
    [ERROR] G:\AndroApp\AppTest\build\android\gen\com\mybilet\apptest\ApptestApplication.java:37: package ti.modules.titanium.platform does not exist
    [ERROR] modules.add(new ti.modules.titanium.platform.PlatformModule(context));
    [ERROR] ^
    [ERROR] 3 errors

    errors, any ideas what i am doing wrong?

    android 2.2, titanium 1.6.1

  11. Manuel says:

    Great tutorial! However I can’t manage to get the setInterval method to get to update the label neither with Android SDK 1.6 or 2.2. Also the background image “crustHeaderBg.png” is not shown, I had to use the workaround that mrgoatee proposed. Is it a known multi platform issue?

  12. Mihai says:

    You need a
    win.open();
    in the main.js, after setting the bg and including the clock.

  13. Palaniraja says:

    I too had the same background issue with crustHeaderBg.png. Modifying the opacity to non zero while intialization in crust.js fixing it.

    //– Crust title background
    var crustTitleView = Ti.UI.createView({
    width:328,
    height:58,
    backgroundImage:’../images/crustHeaderBg.png’,
    top:100,
    left:-6,
    opacity:0.1
    });

    I’m not very sure this is a bug with Titanium or the way we code it.

    @mihai could you please confirm?

    Btw, Thanks for the tutorial @mihai will follow other parts and update as soon as I can.

  14. I had the same problem with the background, but it works with @Palaniraja solution.

    Now, the app doesn’t work, I can see the background for the title, the pizza img, but no scroll. When i click at the right arrow the application shows an error, says that has finished unexpectedly. Do you know what can be wrong?

  15. Hardik says:

    Hey @Palaniraja ,

    It really worked for me… I am also trying to find out wht is wrong with titanium about opacity.. !!! btw thnx for a good suggestion and @Ronnie thnx for such a good tutorial…

  16. Hardik says:

    Hello to all,

    I have gone throught whole tutorial and tried my hand on titanium using this tutorial. Every thing ran ok but “next” is not working for me.. using android 2.2.

  17. Nicola says:

    Great tutorial and I understand it up until the last section, crust.js. I don’t understand how the crust views i.e. var handMade etc, and crusts references i.e. var crusts are linked together. I see that one of them are views that contain the background image, and the other contains the path to the image and a title as well. Isn’t this duplication having the image paths twice? What are they duplicated for?

    Also, I don’t understand the parameters given to next’s event listener, what are they for?

    I hope you don’t mind me asking, but I am really trying to get to grips with titanium and want to understand all I can.

  18. Nicola says:

    Also, the image doesn’t show on android for crusts title view – ./images/crustHeaderBg.png. I tried changing it to select the var’s .image property as you did further down for the next button but it didn’t work. Why isn’t it showing on android?

  19. wat says:

    Dude.

    JS Best Practices for Appcelerator is to use single-context and not open multiple contexts via window url. This opens up memory issues.

    Best way to handle splitting up the files is using CommonJS require() module and writing all of your external files as modules.

    https://wiki.appcelerator.org/display/guides/Mobile+Best+Practices

  20. Prodyot says:

    Excessive Pizza is bad for health.
    I will try not to look at the pizzas and concentrate purely on the codes :)
    Good tut.
    Thanks.

  21. Ibrahim says:

    Great job man really very helpful, after click on pizza should have forum for order details.

    how can I add that to your nice project ?

    Thanks

  22. Thanks for this Tutorial!

    First i thought this tutorial is really great and shows the common way to implement a Titanium Application.

    But: Today i read the best practices from Appcelerator https://wiki.appcelerator.org/display/guides/Mobile+Best+Practices

    “Applications shall run in a single JavaScript context” describes that its not recommended build the Application in the way you show it.

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.