Skip to content

Instantly share code, notes, and snippets.

@bob-sims
Created September 24, 2012 21:53
Show Gist options
  • Save bob-sims/3778685 to your computer and use it in GitHub Desktop.
Save bob-sims/3778685 to your computer and use it in GitHub Desktop.
Staff Directory demo app for Appcelerator #TiMob training

#Overview

I created this simple Staff Directory App as a demonstration for a small internal staff training workshop. Finished product shown below, goal throughout class was to explain code walkthrough and learning resources in pieces, allowing students to create app as a practical exercise.

..

My goals:

  • Show utility of Titanium Mobile to rapidly create simple, x-platform, enterprisey apps (clever term via @thiswayup)
  • Demonstrate use of app template (Master/Detail) included as part of Ti Studio.
  • Demonstrate basic UI elements, events, composite TableView layouts, ImageViews, CommonJS pattern, JSON annotation
  • Replace default splash and icon graphics with custom logo

UI design borrowed from Rafael Streit's excellent BrazilJS app.

To use:

  • Fire up Titanium Studio, create a new Ti Mobile Project, select Master/Detail application template. Complete creation steps as normal, disable ACS.
  • Download image files as zip. Unzip and copy /Resources/iphone and /Resources/android to your project's /Resources folder, merging with the existing /iphone and /android folders. Copy /images folder under your project's /Resources folder.
  • Replace text of /Resources/ui/common/MasterView.js and /Resources/ui/common/DetailView.js with respective content below. Create folder /Resources/data, then create file /Resources/data/data.js with content shown below.
  • Dig around in respective ui/handheld/android - ios - mobileweb and /ui/tablet folders for ApplicationWindow.js to replace "Products" and "Product Details" titles with something more appropriate. :-) Or better yet, abstract these values to an /il8n language file...

Test run in simulator or on device, debug as needed.

Tools

Learning Resources

//some dummy data for our table view
var tableData = [
{
name: 'Batman',
title: 'CIS Branch Head',
phone: '123-4567',
mugshot: 'batman.png',
hasChild: true,
color: '#000',
section: 'Good Guy',
email: '[email protected]'
},
{
name: 'The Joker',
title: 'CIS Engineer',
phone: '123-1232',
mugshot: 'the_joker.png',
hasChild: true,
color: '#000',
email: '[email protected]'
},
{
name: 'Aqua Man',
title: 'CAX Engineer',
phone: '123-3546',
mugshot: 'aqua_man.png',
hasChild: true,
color: '#000',
section: 'Good Guy',
email: '[email protected]'
},
{
name: 'Bane',
title: 'CDE Engineer',
phone: '123-3546',
mugshot: 'bane.png',
hasChild: true,
color: '#000',
email: '[email protected]'
},
{
name: 'Commissioner Gordon',
title: 'INFOSEC Manager',
phone: '123-1111',
mugshot: 'commissioner_gordon.png',
hasChild: true,
color: '#000',
section: 'Good Guy',
email: '[email protected]'
},
{
name: 'Hooded Robin',
title: 'Boy Wonder',
phone: '123-3333',
mugshot: 'hooded_robin.png',
hasChild: true,
color: '#000',
section: 'Good Guy'
},
{
name: 'Scare Crow',
title: 'CIS Event Engineer',
phone: '123-2345',
mugshot: 'scare_crow.png',
hasChild: true,
color: '#000',
email: '[email protected]'
},
{
name: 'Poison Ivy',
title: 'CIS Executive Assistant',
phone: '123-6543',
mugshot: 'poison_ivy.png',
hasChild: true,
color: '#000',
email: '[email protected]'
},
{
name: 'The Penguin',
title: 'CDE Engineer',
phone: '123-3546',
mugshot: 'the_penguin.png',
hasChild: true,
color: '#000',
email: '[email protected]'
},
{
name: 'Mr. Freeze',
title: 'Refrigeration Repair',
phone: '123-3546',
mugshot: 'mr_freeze.png',
hasChild: true,
color: '#000',
email: '[email protected]'
}
];
exports.tableData = tableData;
function DetailView() {
var self = Ti.UI.createView();
self.addEventListener('itemSelected', function(e) {
var headerView = Ti.UI.createView({
height: Ti.UI.SIZE,
backgroundColor: "transparent"
});
var imageProfile = Ti.UI.createImageView({
image: '/images/mugshots/'+e.image,
height: 65,
width: 65,
top: 10,
left: 10,
borderColor: "#444444",
borderWidth: 1,
borderRadius: 4
});
headerView.add(imageProfile);
var labelName = Ti.UI.createLabel({
text: e.name,
left: 85,
top: 20,
color: "#000000",
shadowColor: "#FFFFFF",
shadowOffset: {
x: 0,
y: 1
},
font: {
fontSize: 18,
fontWeight: "bold"
}
});
headerView.add(labelName);
var labelTitle = Ti.UI.createLabel({
text: e.title,
left: 85,
top: 40,
color: "#333333",
shadowColor: "#FFFFFF",
shadowOffset: {
x: 0,
y: 1
},
font: {
fontSize: 15
}
});
headerView.add(labelTitle);
var rowPhone = Ti.UI.createTableViewRow({
phone:e.phone,
height: 44
});
rowPhone.add(Ti.UI.createLabel({
text: "Phone",
left: 10,
font: {
fontSize: 16,
fontWeight: "bold"
},
}));
//add behavior
rowPhone.addEventListener('click', function(e) {
Ti.API.info('dialing: '+rowPhone.phone);
Ti.Platform.openURL('tel:+1'+rowPhone.phone);
});
rowPhone.add(Ti.UI.createLabel({
text: e.phone,
right: 10,
font: {
fontSize: 16
}
}));
var rowEmail = Ti.UI.createTableViewRow({
height: 44,
email: e.email
});
rowEmail.add(Ti.UI.createLabel({
text: "Email",
left: 10,
font: {
fontSize: 16,
fontWeight: "bold"
}
}));
rowEmail.add(Ti.UI.createLabel({
text: e.email,
right: 10,
font: {
fontSize: 16
}
}));
//add behavior
rowEmail.addEventListener('click', function(e) {
Ti.Platform.openURL('mailto:'+rowEmail.email);
Ti.API.info('sending email: '+rowEmail.email);
});
var tableView = Ti.UI.createTableView({
headerView: headerView,
style: Ti.UI.iPhone.TableViewStyle.GROUPED,
data: [rowPhone, rowEmail],
});
self.add(tableView);
});
return self;
};
module.exports = DetailView;
//Master View Component Constructor
function MasterView() {
var tableData = require('data/data').tableData;
var self = Ti.UI.createView({
backgroundColor:'white'
});
var search = Titanium.UI.createSearchBar({
barColor:'#000',
showCancel:true,
height:43,
top:0
});
var sectionGood = Ti.UI.createTableViewSection({headerTitle:'Good Guys'});
var sectionBad = Ti.UI.createTableViewSection({headerTitle:'Bad Guys'});
var tableRows = [];
//
// create our rows
//
for (var i in tableData) {
Ti.API.info('creating row: '+tableData[i].name);
var newRow = Ti.UI.createTableViewRow({
className:'staffRow',
height:70,
name:tableData[i].name,
data:tableData[i]
});
var staffImage = Titanium.UI.createImageView({
top:5,
left:5,
width:60,
height:60,
image:'/images/mugshots/'+tableData[i].mugshot
});
newRow.add(staffImage);
var staffName = Titanium.UI.createLabel({
color:'#000000',
font:{fontSize:'18dp',fontWeight:'bold', fontFamily:'Arial'},
top: "10dp",
left:75,
right:30,
height:Ti.UI.SIZE,
text:tableData[i].name
});
newRow.add(staffName);
var title = Ti.UI.createLabel({
text: tableData[i].title,
top: "30dp",
left: 75,
color: "#666666",
highlightedColor: "#FFFFFF",
font: {
fontSize: "14dp"
}
});
newRow.add(title);
if(tableData[i].section == 'Good Guy') {
sectionGood.add(newRow);
} else {
sectionBad.add(newRow);
}
}
var table = Ti.UI.createTableView({
data:[sectionGood,sectionBad],
search: search,
filterAttribute:'name',
searchHidden:false,
});
self.add(table);
//table.setData([sectionGood,sectionBad]);
table.addEventListener('click', function(e) {
Ti.API.info(JSON.stringify(e.row.data));
self.fireEvent('itemSelected', {
name:e.row.data.name,
title:e.row.data.title,
image:e.row.data.mugshot,
phone:e.row.data.phone,
email:e.row.data.email
});
});
return self;
};
module.exports = MasterView;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment