Documentation : Titanium Tutorial

In tutorial we will create simple application to manage todo tasks for multiple users.

We assume that you are familiar with:

We will start with short description. First of all, creator of assigment will be able to add new tasks, update and delete task. The user will be able only to see other's tasks, complete them, although he will not be able to edit them. Moreover, we will synchronize tasks with Mobeelizer platform.

We will create simple model for task, consisting only of title and description. We will divide oncoming tasks into 5 context:

  • inbox
  • today
  • next
  • someday
  • scheduled

Application will be build of 5 tabs, one for each context. Each tab will present table view with tasks. Additonally, we will provide separate views for editing and adding tasks. 

In order to complete this tutorial, we have to complete several major tasks:

  • design simple model in AppDesigner
  • deploy our application on test enviroment
  • configure app on the mobile
  • use our API to synchronize with Mobeelizer platform

Design Your app

Start working with the Mobeelizer. Create your FREE account.

Open the Mobeelizer App Designer and login with your account. Then, press CREATE NEW APPLICATION button and insert it's name Todo.

In your applications designer panel enter Models section on the left. Then create new model Task.

Now we have to create new fields for Task model.

Name
Required property
Type
Default value property
Additional properties
titleyestext--
descriptionnotext--
contextyesinteger0min: 0 max: 4
completedyesbooleanfalse-

For all fields credentials for role: users-mobile should be:

  • READ - all
  • CREATE - own
  • UPDATE - own

Next section to configure is Groups & Roles, by default there is one group called users and one device category mobile and this two together create role users-mobile. This default configuration is perfect for our example and you don't have to change it. 
When everything is done in Create mode, deploy our application to test environment, and create two users with passwords:

  • a - usera
  • b - userb

Finally, download application definition - Todo.xml. 

Use the Mobeelizer SDK

Open Titanium Studio and create new Titanium Mobile Project. From available templates choose Single Window Application. Proceed. Name application Todo, add App ID. For deployment targets choose iPhone and Android. Last, but not the least uncheck Automatically cloud-enable this application. Remove all js files from ui folder.

Add Mobeelizer SDK module to Titanium project

First of all, add Todo.xml to Resources folder. Then we have to create additional Mobeelizer configuration file. Create new file called mobeelizer.properties inside Resources folder. 

mobeelizer.properties
mode = production
device = mobile
developmentRole = users-mobile
definitionAsset = Todo.xml

mobeelizer.properties

Secondly, we have to download Mobeelizer Titanium SDK. Unzip downloaded file. Now we should have modules folder with two sub-folders: iphone and android. We have to place modules folder in root folder of our application. Then open tiapp.xml  and in GUI add module - ti.mobeelizer.sdk . This should add module definition to tiapp.xml source:

tiapp.xml
<modules>
        <module platform="android" version="1.5.1">ti.mobeelizer.sdk</module>
        <module platform="iphone" version="1.5.1">ti.mobeelizer.sdk</module>
</modules>

From now on, we have configured Mobeelizer SDK. Anywhere we would like to use it we should follow modular javascript from Common.js

var Mobeelizer = require('ti.mobeelizer.sdk');

Add additional resources

There are few files, which are necessery to complete this tutorial: grain.png whiteArrow.png. Create new folder called images in Resources one, and place suche a files in this new folder. You have to also move Ks_nav_ui.png and Ks_nav_views.png files into images folder. We will also need resource file with english names, which should be added to i18n/en folder: strings.xml

Login to Mobeelizer instance

Firstly, we have to edit app.js , which bootstrap file. We would to login on application startup. Currently we will hard-code user. Furthermore, we will save currently logged user for future use.

app.js
(function() {
	var LoggedUser = require('lib/LoggedUser');
	//Obtain Mobeelizer module
	var Mobeelizer = require('ti.mobeelizer.sdk');

	//Login to Mobeelizer instance with asynchronous version
	Mobeelizer.loginToInstance('test', 'a', 'usera', function(e){
		var loggedUser = LoggedUser.getInstance('a');
		var ApplicationTabGroup = require('ui/common/ApplicationTabGroup');
		new ApplicationTabGroup().open();	
	}, function(e){
		Ti.API.info('Error when trying to login to Mobeelizer');
	});
})();

app.js

In Resources folder create new folder called lib. Add new file LoggedUser.js. We have to create singleton, which will hold currently logged user.

LoggedUser.js
var instance;

function LoggedUser(login) {
  this.login = login;
};

function getInstance(login) {
  if (!instance) {
    instance = new LoggedUser(login);
  }
  return instance;
};

exports.getInstance = getInstance;

LoggedUser.js

Create tasks table views

Tasks will be divided into 5 contexts, that is why we will introduce 5 tabs - one for each context. First of all, we will introduce context. Context object will consist of value and name. Value will be mapped on field with same name in task entity. Name property will be used for appropriate labels. Create new file inside lib folder called Context.js

Context.js
module.exports.CONTEXT = {
	INBOX: {value: 0, name: 'inbox'},
	TODAY: {value: 1, name: 'today'},
	NEXT: {value: 2, name: 'next'},
	SCHEDULED: {value: 3, name: 'scheduled'},
	SOMEDAY: {value: 4, name: 'someday'}
};

Context.js

Next we will create tab group, which will hold 5 tabs. Create new file inside ui/common folder called ApplicationTabGroup.js

ApplicationTabGroup.js
function ApplicationTabGroup(Window) {
	var Tab = require('ui/handheld/ApplicationTab');
	var CONTEXT = require('lib/Context').CONTEXT;


	var inboxTab = new Tab(CONTEXT.INBOX); 
	var todayTab = new Tab(CONTEXT.TODAY);
	var nextTab = new Tab(CONTEXT.NEXT);
	var scheduledTab = new Tab(CONTEXT.SCHEDULED);
	var somedayTab = new Tab(CONTEXT.SOMEDAY);

	var self = Ti.UI.createTabGroup();
	self.addTab(inboxTab);
	self.addTab(todayTab);
	self.addTab(nextTab);
	self.addTab(scheduledTab);
	self.addTab(somedayTab);


	return self;
};

module.exports = ApplicationTabGroup;

ApplicationTabGroup.js

Now we will move to creating single tab. Each tab consist only of single window. Create new file inside ui/handheld called ApplicationTab.js

ApplicationTab.js
function ApplicationTab(_context){
	var Window = require('ui/handheld/ApplicationWindow');

	var window = new Window(_context);

	var self = Ti.UI.createTab({
		title: L(_context.name),
		icon: '/images/KS_nav_ui.png',
		window: window
	});
	window.containingTab = self;

   if (Titanium.Platform.name == 'android') {
		var activity = self.activity;
		activity.onCreateOptionsMenu = function(e){
			var menu = e.menu;
    		var syncItem = menu.add({ title: L('sync') });
    		syncItem.addEventListener("click", function(e) {
    			taskTable.beginReloading();
    		});
    	}
 	}

	return self;
};

module.exports = ApplicationTab;

ApplicationTab.js

Then we will create window, which will hold table with task records. 

ApplicationWindow.js
function ApplicationWindow(_context) {
	var TaskTable = require('ui/common/TaskTable');
    var loggedUser = require('lib/LoggedUser').getInstance();

	var self = Ti.UI.createWindow({
		title:L(_context.name),
		backgroundColor:'white'
	});

	var taskTable = new TaskTable(_context);
	self.add(taskTable);

	return self;
};

module.exports = ApplicationWindow;

The most important object in our application is table view with tasks. Table view consists of table view rows. We will create custom table view row. Firstly, task row will consist of label, which presents title of task. Secondly, we will create custom button - checkbox, which will be responsible for completing task. 

Create new file inside ui/common called Checkbox.js

Checkbox.js
function Checkbox(_task) {
	var checkbox = Ti.UI.createButton({
		title : '',
		top : 10,
		left : 10,
		width : 25,
		height : 25,
		borderColor : '#666',
		borderWidth : 2,
		borderRadius : 3,
		backgroundColor : '#aaa',
		backgroundImage : 'none',
		color : '#fff',
		font : {
			fontSize : 25,
			fontWeight : 'bold'
		},
		type : 'checkbox', 
		value : false,
		task: _task
	});
	checkbox.markOn = function() {
		this.backgroundColor = '#0a79ce';
		this.title = '\u2713';
		this.value = true;
	};

	checkbox.markOff = function() {

		this.backgroundColor = '#aaa';
		this.title = '';
		this.value = false;
	};

	return checkbox;
};

module.exports = Checkbox; 

We will add click event listener to checkbox. In addition to marking button properly, when pushing button we will complete task.

Checkbox.js
	checkbox.completeTask = function() {
		//Obtain Mobeelizer object
		var Mobeelizer = require('ti.mobeelizer.sdk');
		//Get Mobeelizer database object
		var database = Mobeelizer.getDatabase();

		//Modify task entity
		this.task.putField('completed', true);

		//Update task in Mobeelizer database
		database.save(this.task);
	};

	checkbox.addEventListener('click', function(e) {
		var LoggedUser = require('lib/LoggedUser');
		var loggedUser = LoggedUser.getInstance();

		//Only creator of task can complete it
		if (false === e.source.value && e.source.task.owner === loggedUser.login) {
			e.source.markOn();
			e.source.completeTask();
		} else {
			e.source.markOff();
		}
	});

Checkbox.js

Now we will move to creating custom table view row. Each row will be associated with unique task. We will mark user's records with black label and other's tasks with blue label. Task view row label will be task's title field. Moreover, we will set row to editable - this property will enable swipe action on row, which presents delete button. Create new file inside ui/common called TaskRow.js

TaskRow.js
function TaskRow(_task) {
	var LoggedUser = require('lib/LoggedUser');

	var loggedUser = LoggedUser.getInstance();
	var Checkbox = require('ui/common/Checkbox');

	var self = Ti.UI.createTableViewRow();
	var checkbox = new Checkbox(_task);
	var title = Ti.UI.createLabel({
		color: _task.getOwner() === loggedUser.login ? '#222' : '#003EFF',
		font : {
			fontSize : '20',
			fontWeight : 'bold'
		},
		left : 50,
		top : 10,
		width : 'auto',
		text : _task.getField('title')
	});

	self.add(checkbox);
	self.add(title);


	self.hasChild = true;
	self.backgroundColor = '#eee';
	self.editable = true;
	self.task = _task;
	self.height = 45;


	return self;
};

module.exports = TaskRow; 

TaskRow.js

Finally, we will create table view. Each table view is connected with one context. 

TaskTable.js
function TaskTable(_context){
    var loggedUser = require('lib/LoggedUser').getInstance();
	
    var tableView = Ti.UI.createTableView({
		separatorColor: '#444',
		backgroundColor: 'transparent',
		backgroundImage: 'images/grain.png'
	});

	return tableView;
};

module.exports = TaskTable;

We will add function to populate table with data. Records will be obtained from Mobeelizer database based on context. We will add listener for databaseUpdated event, which will update table content.

TaskTable.js
	function populateData() {
		var TaskRow = require('ui/common/TaskRow');
		//Obtain Mobeelizer object
		var Mobeelizer = require('ti.mobeelizer.sdk');
		//Get Mobeelizer database object
		var database = Mobeelizer.getDatabase();
		//Get tasks for choosen context and uncompleted from Mobeelizer database
		var tasks = database.find('Task')
							.add(database.Restriction.eq('context', _context.value))
							.add(database.Restriction.eq('completed', false))
							.list();
		var rows =[];
		for (var i=0 ; i<tasks.length ; i++)
		{ 
			rows.push(new TaskRow(tasks[i]));
		}					
		tableView.setData(rows);
	}

	populateData();
	Ti.App.addEventListener('databaseUpdated', populateData);

Now we will add opportunity to synchronize records with Mobeelizer cloud. Synchronization will be launched on pull table view. 

TaskTable.js
var border = Ti.UI.createView({
		backgroundColor:"#576c89",
		height:2,
		bottom:0
	});
 
	var tableHeader = Ti.UI.createView({
		backgroundColor:"#e2e7ed",
		width:320,
		height:60
	});
	tableHeader.add(border);

	var arrow = Ti.UI.createView({
		backgroundImage:'images/whiteArrow.png',
		width:23,
		height:60,
		bottom:10,
		left:20
	});

 	var statusLabel = Ti.UI.createLabel({
		text:"Pull to reload",
		left:55,
		width:200,
		bottom:30,
		height:"auto",
		color:"#576c89",
		textAlign:"center",
		font:{fontSize:13,fontWeight:"bold"},
		shadowColor:"#999",
		shadowOffset:{x:0,y:1}
	});

 	var lastUpdatedLabel = Ti.UI.createLabel({
		text:"Last Updated: "+formatDate(),
		left:55,
		width:200,
		bottom:15,
		height:"auto",
		color:"#576c89",
		textAlign:"center",
		font:{fontSize:12},
		shadowColor:"#999",
		shadowOffset:{x:0,y:1}
	});
	var actInd = Titanium.UI.createActivityIndicator({
		left:20,
		bottom:13,
		width:30,
		height:30
	});

	function formatDate(){
		var date = new Date;
		var datestr = date.getMonth()+'/'+date.getDate()+'/'+date.getFullYear();
		if (date.getHours()>=12){
           datestr+=' '+(date.getHours()==12 ? 
              date.getHours() : date.getHours()-12)+':'+
              date.getMinutes()+' PM';
		}
		else{
			datestr+=' '+date.getHours()+':'+date.getMinutes()+' AM';
		}
		return datestr;
	}

	tableHeader.add(arrow);
	tableHeader.add(statusLabel);
	tableHeader.add(lastUpdatedLabel);
	tableHeader.add(actInd);
	tableView.headerPullView = tableHeader;

	var pulling = false;
	var reloading = false;

	tableView.beginReloading = function(){
		//Obtain Mobeelizer object
		var Mobeelizer = require('ti.mobeelizer.sdk');

		//Synchronize with Mobeelizer cloud
		Mobeelizer.sync(function(){
			populateData();
			endReloading(true);
		}, function(e){
			Ti.API.error('There was an error when trying to synchronize ');
			endReloading(false);
		});
	};

	function endReloading(success){
		tableView.setContentInsets({top:0},{animated:true});
		reloading = false;
		if(success){
			lastUpdatedLabel.text = "Last Updated: "+formatDate();
		}
		statusLabel.text = "Pull down to refresh...";
		actInd.hide();
		arrow.show();
	};

	tableView.addEventListener('scroll', function(e) {
		var offset = e.contentOffset.y;
		if (offset <= -65.0 && !pulling) {
			var t = Ti.UI.create2DMatrix();
			t = t.rotate(-180);
			pulling = true;
			arrow.animate({
				transform : t,
				duration : 180
			});
			statusLabel.text = "Release to refresh...";
		} else if (pulling && offset > -65.0 && offset < 0) {
			pulling = false;
			var t = Ti.UI.create2DMatrix();
			arrow.animate({
				transform : t,
				duration : 180
			});
			statusLabel.text = "Pull down to refresh...";
		}
	});

	tableView.addEventListener('dragEnd', function() {
		if (pulling && !reloading) {
			reloading = true;
			pulling = false;
			arrow.hide();
			actInd.show();
			statusLabel.text = "Reloading...";
			tableView.setContentInsets({
				top : 60
			}, {
				animated : true
			});

			tableView.scrollToTop(-60, true);
			arrow.transform = Ti.UI.create2DMatrix();
			beginReloading();
		}
	}); 

Last, but not the least we have to add delete logic into task table, on iPhone we will add new delete event listener, on android will display option menu when user long press on table item.

TaskTable.js
if(Titanium.Platform.osname==='iphone'){
	tableView.addEventListener('delete', function(e){
		//Obtain Mobeelizer object
		var Mobeelizer = require('ti.mobeelizer.sdk');
		//Get Mobeelizer database
		var database = Mobeelizer.getDatabase();
		//Remove entity from Mobeelizer database
		database.removeObject(e.row.task);	
	});
}
if (Titanium.Platform.name == 'android') {
    tableView.addEventListener('longclick', function(e){
		var task = e.row.task;
        if(task.getOwner() === loggedUser.login){
        	var opts = {
			  cancel: 1,
			  options: [L('yes'), L('no')],
			  selectedIndex: 1,
			  destructive: 0,
			  title: L('deleteTask')
			};
			var dialog = Ti.UI.createOptionDialog(opts);
        	dialog.addEventListener('click',function(e){
        		if(e.index === 0){
		        		//Obtain Mobeelizer object
			        var Mobeelizer = require('ti.mobeelizer.sdk');
			        //Get Mobeelizer database
			        var database = Mobeelizer.getDatabase();
			        //Remove entity from Mobeelizer database
			        database.removeObject(task);	
		        	populateData();	
        		}
        	});
        	dialog.show();
	        
        }
    });
}

TaskTable.js

Create task detail view

We will create detail view for task. We will add event listener to click event. When user clicks on table view row, there are two possibilities. Firstly, when user pushes checkbox, task will be completed. Otherwise, we will move to task detail page. 

ApplicationWindow.js
	taskTable.addEventListener('click', function(e){
		if(e.source.type !== 'checkbox'){
			var TaskDetailWindow = require('ui/handheld/TaskDetailWindow');
			self.containingTab.open(new TaskDetailWindow(e.row.task));
		}else if(e.row.task.getOwner() === loggedUser.login){
			taskTable.deleteRow(e.index, {animated: true});
		}
	});

Then we will create detail view for task. We will create textfield, textarea and label for each of those. All fields are editable only to creator of task. If owner is editing task, there will be also context picker with label. We can also update task inside Add new file inside ui/handheld folder called TaskDetailWindow.js

TaskDetailWindow.js
 function TaskDetailWindow(_task) {
	var ContextPicker = require('ui/common/ContextPicker');
	var loggedUser = require('lib/LoggedUser').getInstance();
	var editable = (_task.getOwner() === loggedUser.login);
 	
	var self = Ti.UI.createWindow({ 
 		title : L('info'),  
		backgroundColor : 'transparent',
  		backgroundImage : 'images/grain.png',
		layout : 'vertical'
	});

 	var titleLabel = Ti.UI.createLabel({ text : L('title'),   		top : 10,
		left : 10,
		font : {
			fontWeight : 'bold',
			fontSize : 18
		},
		color : '#fff',
		height : Ti.UI.SIZE
	});

	var titleTextField = Ti.UI.createTextField({
		top : 10,
		left : 10,
		right : 10,
		height : Ti.UI.SIZE,
		value : _task.getField('title'),
		borderStyle : Ti.UI.INPUT_BORDERSTYLE_ROUNDED,
		editable : editable
	});

	var descriptionLabel = Ti.UI.createLabel({
		text : L('description'),
		top : 20,
		left : 10,
		font : {
			fontWeight : 'bold',
			fontSize : 18
		},
		color : '#fff',
		height : Ti.UI.SIZE
	});

	var descriptionTextArea = Ti.UI.createTextArea({
		top : 10,
		left : 10,
		right : 10,
		height : 70,
		borderRadius : 5,
		font : {
			fontSize : 14
		},
		value : _task.getField('description'),
		editable : editable
	});

	self.add(titleLabel);
	self.add(titleTextField);
	self.add(descriptionLabel);
	self.add(descriptionTextArea);

	if (editable) {
		var contextLabel = Ti.UI.createLabel({
			text : L('context'),
			top : 20,
			left : 10,
			font : {
				fontWeight : 'bold',
				fontSize : 18
			},
			color : '#fff',
			height : Ti.UI.SIZE
		});

		var contextPicker = new ContextPicker();
		contextPicker.setSelectedRow(0, _task.getField('context'));
		contextPicker.setEditable(editable);

		self.add(contextLabel);
		self.add(contextPicker);
	}
	return self;
};

module.exports = TaskDetailWindow;

We will add save button to detail page. We will add click event listener to update task in Mobeelizer database.

TaskDetailWindow.js
function save(){
	//Obtain Mobeelizer object
	var Mobeelizer = require('ti.mobeelizer.sdk');
	//Get Mobeelizer database
	var database = Mobeelizer.getDatabase();
	//Update task entity
	_task.putField('title', titleTextField.value);
	_task.putField('description', descriptionTextArea.value);
	_task.putField('context', contextPicker.getSelectedRow(0).context.value);
	//Update Mobeelizer task
	var error = database.save(_task);
	if (error) {
		Ti.API.error('There was an error while trying to update task');
	} else {
		Ti.App.fireEvent("databaseUpdated");
		self.close();
	}
}
if (Titanium.Platform.name == 'iphone') {
	var saveButton = Titanium.UI.createButton({
		title : L('save'),
		style : Titanium.UI.iPhone.SystemButtonStyle.PLAIN
	});
	saveButton.addEventListener('click', save);
	self.setRightNavButton(saveButton);
}
else if(Titanium.Platform.name == 'android' && editable) {
    var activity = self.activity;
	activity.onCreateOptionsMenu = function(e){
		var menu = e.menu;
		var menuItem = menu.add({ title: L('save') });
    	menuItem.addEventListener("click", save);
    }
}

TaskDetailWindow.js

We have used custom picker to choose appropriate context for task. Create new file inside ui/common folder called ContextPicker.js

ContextPicker.js
function ContextPicker(){
	var CONTEXT = require('lib/Context').CONTEXT;

	var rows = [];
	for(var c  in CONTEXT){
		var row = Ti.UI.createPickerRow({
			title: L(CONTEXT[c].name),
			context: CONTEXT[c]
		});
		rows.push(row);
	}

	var self = Ti.UI.createPicker({
		top: 10,
		selectionIndicator: true
	});
	self.add(rows);

	return self;
};

module.exports = ContextPicker;

ContextPicker.js

Add new tasks

Finally, we will create view for adding new tasks. We will add button to ApplicationWindow.js on iPhone platform, on android we will add new item into the menu.

ApplicationWindow.js
    if (Titanium.Platform.name == 'android') {
		var activity = self.activity;
		activity.onCreateOptionsMenu = function(e){
			var menu = e.menu;
    		var menuItem = menu.add({ title: L('newTask') });
    		menuItem.addEventListener("click", function(e) {
    			var AddTaskWindow = require('ui/handheld/AddTaskWindow');
		    	self.containingTab.open(new AddTaskWindow(_context));
    		});
    		var syncItem = menu.add({ title: "Synchronize" });
    		syncItem.addEventListener("click", function(e) {
    			taskTable.beginReloading();
    		});
    	}
 	}
 	
	if(Titanium.Platform.osname==='iphone'){
		var addButton = Titanium.UI.createButton({systemButton: Ti.UI.iPhone.SystemButton.ADD});
		addButton.addEventListener('click',function() {
	    	var AddTaskWindow = require('ui/handheld/AddTaskWindow');
		    self.containingTab.open(new AddTaskWindow(_context));
		});
	
		self.setRightNavButton(addButton);
	}

ApplicationWindow.js

Now we will create view for adding new task. We will create layout with textfield, textarea, context picker and label for each of those component. Add new file inside ui/handheld called AddTaskWindow.js

AddTaskWindow.js
function AddTaskWindow(_context){
	var ContextPicker = require('ui/common/ContextPicker');

	var self = Ti.UI.createWindow({
		title:L('newTask'),
		layout:'vertical',
		backgroundColor: 'transparent',
		backgroundImage: 'images/grain.png'
	});

 	var titleLabel = Ti.UI.createLabel({ 
		text:L('title'),
		top:10,
		left: 10,
		font: {
			fontWeight:'bold',
			fontSize:18
		},
		color: '#fff',
		height:Ti.UI.SIZE
	});

	var titleTextField = Ti.UI.createTextField({
		top: 10,
 		left: 10, 

		right:10,
		height: Ti.UI.SIZE,
		borderStyle: Ti.UI.INPUT_BORDERSTYLE_ROUNDED
	});

	var descriptionLabel = Ti.UI.createLabel({
		text:L('description'),
		top:20,
		left: 10,
		font: {
			fontWeight:'bold',
			fontSize:18
		},
		color: '#fff',
		height:Ti.UI.SIZE
	});

	var descriptionTextArea = Ti.UI.createTextArea({
		top: 10,
		left: 10,
		right:10,
		height: 70,
		borderRadius: 5,
		font: {
			fontSize: 14
		}
	});

	var contextLabel = Ti.UI.createLabel({
		text:L('context'),
		top:20,
		left: 10,
		font: {
			fontWeight:'bold',
			fontSize:18
		},
		color: '#fff',
		height:Ti.UI.SIZE
	});

	var contextPicker = new ContextPicker();
	contextPicker.setSelectedRow(0, _context.value);

 	self.add(titleLabel); 
	self.add(titleTextField);
	self.add(descriptionLabel);
	self.add(descriptionTextArea);
	self.add(contextLabel);
	self.add(contextPicker);

	return self;
};
    module.exports = AddTaskWindow;  

Then we will add save button. We will store new task in Mobeelizer database.

AddTaskWindow.js
    function save(){
    	//Obtain Mobeelizer object
        var Mobeelizer = require('ti.mobeelizer.sdk');
        //Get Mobeelizer database
        var database = Mobeelizer.getDatabase();
        //Get new task entity
        var task = database.entity('Task'); 
        //Fill task entity
        task.putField('title', titleTextField.value);
        task.putField('description', descriptionTextArea.value);
        task.putField('context', contextPicker.getSelectedRow(0).context.value);
        task.putField('completed', false);
        //Save task entity in Mobeelizer database
        var error = database.save(task);
        if(error){
            Ti.API.error('There was an error while trying to add task ' + error);
        }else{
            Ti.App.fireEvent("databaseUpdated");
            self.close();   
        }
    }
    if (Titanium.Platform.name == 'ios') {
        var saveButton = Titanium.UI.createButton({
			title:L('save'),
			style:Titanium.UI.iPhone.SystemButtonStyle.PLAIN
		});
		saveButton.addEventListener('click', save);		
    }
    else if (Titanium.Platform.name == 'android') {
		var activity = self.activity;
		activity.onCreateOptionsMenu = function(e){
			var menu = e.menu;
    		var menuItem = menu.add({ title: L('save') });
    		menuItem.addEventListener("click", save);
    	}
 	}

AddTaskWindow.js

Conclusion

To conclude, this example presents synchronization in Mobeelizer system. Now we should be able to create application using AppDesigner, create new models with needed fields. We have also seen how credentials to fields affect application. Moreover, we have seen how to connect Mobeelizer SDK module to Titanium project and how to use Mobeelizer SDK. Tutorial presents creating, reading, updating and deleting entities from Mobeelizer database both with synchronization to Mobeelizer cloud.
strings.xml 

 

Attachments:

Todo application.png (image/png)
Task model.png (image/png)
Title field.png (image/png)
Description field.png (image/png)
Context field.png (image/png)
Completed field.png (image/png)
mobeelizer.properties (application/octet-stream)
app.js (text/javascript)
LoggedUser.js (text/javascript)
Context.js (text/javascript)
ApplicationTabGroup.js (text/javascript)
ApplicationTab.js (text/javascript)
Checkbox.js (text/javascript)
TaskRow.js (text/javascript)
TaskTable.js (text/javascript)
TaskDetailWindow.js (text/javascript)
ContextPicker.js (text/javascript)
ApplicationWindow.js (text/javascript)
AddTaskWindow.js (text/javascript)
grain.png (image/png)
whiteArrow.png (image/png)
strings.xml (text/xml)
strings.xml (text/xml)
strings.xml (text/xml)
strings.xml (text/xml)
TaskTable.js (application/x-javascript)