Created
October 5, 2012 20:38
-
-
Save Mindelusions/3842244 to your computer and use it in GitHub Desktop.
TodoListACS - Blog Post Code Samples
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* AddWindow.js is the simple modal form for adding new tasks. | |
*/ | |
function AddWindow() { | |
var todo = require('todo'); | |
var self = Ti.UI.createWindow({ | |
backgroundColor:'#fff', | |
layout:'vertical', | |
modal:true, | |
title:'Add Item' | |
}); | |
// The title for the new task. | |
var itemField = Ti.UI.createTextField({ | |
width:'90%', | |
height:Ti.UI.SIZE, | |
hintText:'What do you need to do?', | |
top:20, | |
borderStyle:Ti.UI.INPUT_BORDERSTYLE_ROUNDED | |
}); | |
// Listen for the 'return' event on the new task field. | |
itemField.addEventListener('return', function() { | |
if (itemField.value === '') { | |
alert("Please enter an item."); | |
} else { | |
todo.add(itemField.value); | |
self.close(); | |
} | |
}); | |
self.add(itemField); | |
// Add button | |
var addBtn = Ti.UI.createButton({ | |
title:'Add Item', | |
width:'50%', | |
height:Ti.UI.SIZE, | |
borderStyle:Ti.UI.INPUT_BORDERSTYLE_ROUNDED, | |
top:20 | |
}); | |
// Click to add new task. | |
addBtn.addEventListener('click', function() { | |
if (itemField.value === '') { | |
alert("Please enter an item."); | |
} else { | |
todo.add(itemField.value); | |
self.close(); | |
} | |
}); | |
self.add(addBtn); | |
// Cancel the add task and close the window. | |
var cancelBtn = Ti.UI.createButton({ | |
title:'Cancel', | |
width:'50%', | |
height:Ti.UI.SIZE, | |
borderStyle:Ti.UI.INPUT_BORDERSTYLE_ROUNDED, | |
top:10 | |
}); | |
cancelBtn.addEventListener('click', function() { | |
self.close(); | |
}); | |
self.add(cancelBtn); | |
return self; | |
} | |
module.exports = AddWindow; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// app.js doing only what it needs to do ... bootstrap | |
if (Ti.version < 1.8 ) { | |
alert('Sorry - this application template requires Titanium Mobile SDK 1.8 or later'); | |
} else { | |
(function() { | |
var ApplicationTabGroup = require('ui/ApplicationTabGroup'); | |
new ApplicationTabGroup().open(); | |
})(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* ApplicationTabGroup.js creates the tab group and list windows for the app. | |
*/ | |
function ApplicationTabGroup() { | |
var self = Ti.UI.createTabGroup(), | |
ListWindow = require('ui/ListWindow'); | |
// Create the task windows. Both windows are created using the | |
// ListWindow passing isDone flag to determine the list. | |
var todoWin = new ListWindow({ | |
title:'Todo', | |
backgroundColor:'#fff', | |
navBarHidden:false, | |
isDone:false, | |
// Add a menu option for Android to add new tasks. | |
// For iOS we will add a button as the rightNavButton on the window | |
activity: { | |
onCreateOptionsMenu: function(e) { | |
var menu = e.menu; | |
var menuItem = menu.add({ title: "Add Task" }); | |
menuItem.setIcon("images/ic_menu_add.png"); | |
menuItem.addEventListener("click", function(e) { | |
var AddWindow = require('ui/AddWindow'), | |
addWin = new AddWindow(); | |
addWin.open(); | |
}); | |
} | |
} | |
}), | |
doneWin = new ListWindow({ | |
title:'Done', | |
backgroundColor:'#fff', | |
navBarHidden:false, | |
isDone:true | |
}); | |
var todoTab = Ti.UI.createTab({ | |
title: 'Todo', | |
icon: '/images/KS_nav_ui.png', | |
window: todoWin | |
}); | |
todoWin.containingTab = todoTab; | |
var doneTab = Ti.UI.createTab({ | |
title: 'Done', | |
icon: '/images/KS_nav_views.png', | |
window: doneWin | |
}); | |
doneWin.containingTab = doneTab; | |
self.addTab(todoTab); | |
self.addTab(doneTab); | |
// When the tabgroup opens, launch the login window as a modal window. | |
// TODO: Store the session id and restore the session automatically if | |
// it exists. This would bypass the login screen and fetch the users tasks | |
self.addEventListener('open', function() { | |
var LoginWindow = require('ui/LoginWindow'), | |
loginWin = new LoginWindow(); | |
loginWin.open({modal:true}); | |
}); | |
return self; | |
}; | |
module.exports = ApplicationTabGroup; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* ListWindow.js controls both the todo list and the done list. _args.isDone flag is | |
* used to determine which list we are processing for. | |
*/ | |
var platform = Ti.Platform.osname; | |
function ListWindow(_args) { | |
var todo = require('todo'); | |
// Tableview will initially be blank until we have a logged in user. | |
var self = Ti.UI.createWindow(_args), | |
tblView = Ti.UI.createTableView({ | |
data:[] | |
}), | |
isDone = _args.isDone; | |
// Listener for completing and deleting tasks | |
tblView.addEventListener('click', function(e) { | |
var btns, handler; | |
if (isDone) { | |
// If we're looking at the completed task list, we only want to be able to | |
// delete any given task. | |
btns = ['Delete', 'Cancel']; | |
handler = function(evt) { | |
if (evt.index === 0) { | |
todo.remove(e.row.id); | |
todo.fetch(); | |
} | |
}; | |
} else { | |
// If we are looking at the todo task list, we can mark it as done, or | |
// delete the task all together. | |
btns = ['Done', 'Delete', 'Cancel']; | |
handler = function(evt) { | |
if (evt.index === 0) { | |
todo.done(e.row.id); | |
todo.fetch(); | |
} else if (evt.index === 1) { | |
todo.remove(e.row.id); | |
todo.fetch(); | |
} | |
}; | |
} | |
// Build the confirm dialog for changing tasks. | |
var confirm = Ti.UI.createAlertDialog({ | |
title:'Change Task Status', | |
message:e.title, | |
buttonNames:btns | |
}); | |
confirm.addEventListener('click', handler); | |
confirm.show(); | |
}); | |
self.add(tblView); | |
// Here we are adding the 'add' button to iOS and mobile web | |
// windows, but only on the task window. For Android, we added | |
// a menu option to add new tasks. | |
if (!isDone && platform !== 'android') { | |
var addBtn = Ti.UI.createButton({ | |
title:'+' | |
}); | |
addBtn.addEventListener('click', function() { | |
// Show Add Window | |
var AddWindow = require('ui/AddWindow'), | |
addWin = new AddWindow(); | |
addWin.open(); | |
}); | |
self.rightNavButton = addBtn; | |
} | |
// If we are looking at the todo task list we listen for an app level | |
// event to quickly add new tasks without making another ACS call. | |
if (!isDone) { | |
Ti.App.addEventListener('app:todo_added', function(_todo) { | |
var row = Ti.UI.createTableViewRow({ | |
title:_todo.title, | |
id:_todo.id | |
}); | |
tblView.appendRow(row); | |
}); | |
} | |
// Here we are listening for an app level event that will update both task lists. | |
// We fetch all tasks for a given user and then separate them based on their status. | |
Ti.App.addEventListener('app:update_tables', function(_todos) { | |
Ti.API.info("UPDATE: "+JSON.stringify(_todos)); | |
var dolist = [], donelist = [], | |
i = 0, len = _todos.tasks.length, | |
row, todo; | |
for ( ; i < len; i++) { | |
todo = _todos.tasks[i]; | |
row = Ti.UI.createTableViewRow({ | |
title:todo.title, | |
id:todo.id | |
}); | |
if (todo.done) { | |
donelist.push(row); | |
} else { | |
dolist.push(row); | |
} | |
} | |
if (isDone) { | |
tblView.setData(donelist); | |
} else { | |
tblView.setData(dolist); | |
} | |
}); | |
return self; | |
} | |
module.exports = ListWindow; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* LoginWindow.js is the simple login form for the app. If a user and pass does not exist in | |
* ACS, then a new account is automatically created using those credentials. | |
*/ | |
function LoginWindow() { | |
var todo = require('todo'); | |
var self = Ti.UI.createWindow({ | |
backgroundColor:'#fff', | |
layout:'vertical', | |
title:'Todo Login' | |
}); | |
var lbl = Ti.UI.createLabel({ | |
text:'Login / Signup', | |
font:{ | |
fontWeight:'bold', | |
fontSize:16 | |
}, | |
top:20 | |
}); | |
self.add(lbl); | |
// Username field | |
var userField = Ti.UI.createTextField({ | |
width:'90%', | |
height:Ti.UI.SIZE, | |
hintText:'Username', | |
borderStyle:Ti.UI.INPUT_BORDERSTYLE_ROUNDED, | |
top:10 | |
}); | |
self.add(userField); | |
// Password field | |
var passField = Ti.UI.createTextField({ | |
width:'90%', | |
height:Ti.UI.SIZE, | |
hintText:'Password', | |
borderStyle:Ti.UI.INPUT_BORDERSTYLE_ROUNDED, | |
passwordMask:true, | |
top:10 | |
}) | |
// Adding a 'return' listener so that the form is submitted | |
// whens the Return key is pressed. | |
passField.addEventListener('return', function() { | |
todo.login({ | |
login:userField.value, | |
password:passField.value | |
}); | |
}); | |
self.add(passField); | |
// login button | |
var loginBtn = Ti.UI.createButton({ | |
title:'Login', | |
width:Ti.UI.SIZE, | |
height:Ti.UI.SIZE, | |
top:20 | |
}); | |
// submit the form when login button is clicked | |
loginBtn.addEventListener('click', function(){ | |
todo.login({ | |
login:userField.value, | |
password:passField.value | |
}); | |
}); | |
self.add(loginBtn); | |
// On a successful login, close this modal window | |
Ti.App.addEventListener('app:login_success', function() { | |
self.close(); | |
}); | |
return self; | |
} | |
module.exports = LoginWindow; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* todo.js replaces the db.js from the original todo sample with some additions. Here we'll be handling | |
* all cloud interaction including User and Task handling. | |
*/ | |
var Cloud = require('ti.cloud'); | |
// Store the userid and username for quick access | |
exports.storeUser = function(_user) { | |
Ti.App.Properties.setString('todo_uid', _user.id); | |
Ti.App.Properties.setString('todo_username', _user.username); | |
}; | |
// Register a new user with ACS. | |
exports.register = function(_args) { | |
Cloud.Users.create(_args, function(e) { | |
if (e.success) { | |
alert("Registration Successful"); | |
exports.storeUser(e.users[0]); | |
Ti.App.fireEvent('app:login_success'); | |
} else { | |
alert('Error:\\n' + ((e.error && e.message) || JSON.stringify(e))); | |
} | |
}); | |
}; | |
// Login an ACS user. If the user does not exist we automatically shoot the | |
// credentials off to register a new user. If a user is successfully logged in | |
// we immediately call the fetch() method to grab existing tasks. | |
exports.login = function(_args) { | |
Cloud.Users.login(_args, function(e) { | |
if (e.success) { | |
alert("Login Successful!"); | |
exports.storeUser(e.users[0]); | |
exports.fetch(); | |
Ti.App.fireEvent('app:login_success'); | |
} else { | |
exports.register({ | |
username:_args.login, | |
password:_args.password, | |
password_confirmation:_args.password | |
}); | |
} | |
}); | |
}; | |
// Logout the current user. | |
exports.logout = function() { | |
Cloud.Users.logout(function (e) { | |
if (e.success) { | |
alert('Success: Logged out'); | |
} else { | |
alert('Error:\\n' + ((e.error && e.message) || JSON.stringify(e))); | |
} | |
}); | |
}; | |
// Creating a classname for custom objects based on the username | |
exports.getClass = function() { | |
return Ti.App.Properties.getString('todo_username') + "_todo"; | |
}; | |
// Fetch all of the tasks for a given user. Once we retrieve those | |
// tasks fire an event to update the task lists. | |
exports.fetch = function() { | |
var classname = exports.getClass(); | |
Cloud.Objects.query({ | |
classname:classname, | |
limit:100 | |
}, function(e) { | |
if (e.success) { | |
Ti.API.info("SUCCESS:"+JSON.stringify(e)); | |
Ti.App.fireEvent('app:update_tables', {tasks:e[classname]}); | |
} else { | |
alert('Error:\\n' + ((e.error && e.message) || JSON.stringify(e))); | |
} | |
}); | |
} | |
// Add a new task. Once a task is added, we fire an event to the task window | |
// that will add the new task to the task list without the need to make a | |
// new call to ACS. | |
exports.add = function(_title) { | |
var classname = exports.getClass(); | |
Cloud.Objects.create({ | |
classname: classname, | |
fields: { | |
title:_title, | |
done:false | |
} | |
}, function(e) { | |
if (e.success) { | |
alert("Task Added!"); | |
Ti.App.fireEvent('app:todo_added', e[classname][0]); | |
} else { | |
alert('Error:\\n' + ((e.error && e.message) || JSON.stringify(e))); | |
} | |
}); | |
}; | |
// Remove a task from the users task list. | |
exports.remove = function(_id) { | |
var classname = exports.getClass(); | |
Cloud.Objects.remove({ | |
classname: classname, | |
id: _id | |
}, function (e) { | |
if (e.success) { | |
alert('Task Removed'); | |
} else { | |
alert('Error:\\n' + ((e.error && e.message) || JSON.stringify(e))); | |
} | |
}); | |
}; | |
// Mark a task as complete | |
exports.done = function(_id) { | |
var classname = exports.getClass(); | |
Cloud.Objects.update({ | |
classname:classname, | |
id:_id, | |
fields:{ | |
done:true | |
} | |
}, function(e) { | |
if (e.success) { | |
alert('Task Complete'); | |
} else { | |
alert('Error:\\n' + ((e.error && e.message) || JSON.stringify(e))); | |
} | |
}); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment