Example #1
0
exports.createCheckbox = function(titleid, properties, useTitle) {
	return Ti.UI.createSwitch(
		_.extend(
			_.defaults(properties || {}, 
				useTitle? { title: titleid } : { titleid: titleid }	
			),
			{ style: Ti.UI.Android.SWITCH_STYLE_CHECKBOX }
		)
	)
}
Example #2
0
	remove: function(idOrQuery) {
		if (_.isString(idOrQuery)) {
			return this.makeRequest(this.COLLECTION, this.REQUEST.DELETE, { id: idOrQuery }, {})	
		}
		else if (_.isObject(idOrQuery)) {
			//to remove multiple entries, we have to send an empty LIST with PUT (not empty object)
			return this.makeRequest(this.COLLECTION, this.REQUEST.REPLACE, [], { q: idOrQuery })
		}
		else {
			return new Error('Argument idOrQuery of Model.remove should be a string or query object, given: '+JSON.stringify(idOrQuery))
		}
	},
Example #3
0
exports.createLabel = function(properties) {
	return Ti.UI.createLabel(_.defaults(properties || {}, {
		width: '100%',
		color: color.text,
		textAlign: Ti.UI.TEXT_ALIGNMENT_LEFT
	}))	
}
Example #4
0
	saveData: function(data) {
		return this.makeRequest(
			this.COLLECTION,
			(data.id)? this.REQUEST.REPLACE : this.REQUEST.INSERT,
			_.pick(data, this.fields)
		)
	},
Example #5
0
		_.each(this.fields, function(field) {
			if (field == 'id' && _.has(values, '_id')) {
				this.id = values._id.$oid
			}
			else {
				this[field] = values[field]
			}
		}, this)
Example #6
0
		    _.each(queryString, function(data, key) {
		    	if (typeof data == 'object' && _.keys(data).length == 0) return
		    	else {
		    		//TODO: this is not handling regular expressions correctly: JSON.stringify returns {}
		    		//for RegExp objects. They should be recursively filtered and handled separately 
					var encodedData = encodeURIComponent((key == 'q')? JSON.stringify(data) : data)        
		        	qsParts.push(key+'='+encodedData)
		        }
		    })
Example #7
0
exports.createTextField = function(properties) {
	var defaultValues = {
		width: '100%',
		backgroundColor: color.field.bg,
		color: color.field.color
	}
	
	if (iOS) {
		_.extend(defaultValues, {
		//borderColor: darkGray,
		borderStyle: Ti.UI.INPUT_BORDERSTYLE_ROUNDED,
		//borderRadius: 10,
		//borderWidth: 1
		})
	}
	
	return Ti.UI.createTextField(_.defaults(properties || {}, defaultValues))	
}
Example #8
0
	updateData: function(id, newData) {
		var _newData = _(newData)
		
		if (_newData.has('$push') || _newData.has('$unset') || _newData.has('$set'))
			_.extend(newData, { id: id })
		else
			newData = { $set: newData, id: id }
			
		return this.makeRequest(this.COLLECTION, this.REQUEST.UPDATE, newData, {})
	},
Example #9
0
exports.createSimplePicker = function(data, properties, useTitle) {
	var rows = [],
		picker = Ti.UI.createPicker(_.defaults(properties || {}, {
			width: '100%'
		}))
	
	for (var i in data)
		rows[i] = Ti.UI.createPickerRow( useTitle? { title: data[i] } : { titleid: data[i] } )
		
	picker.add(rows)
	
	if (properties.selectedRow)
		picker.setSelectedRow(0, properties.selectedRow, false)
	
	return picker
}
Example #10
0
				onload: function(source) {
					response = JSON.parse(this.responseText)
					if (response === null) response = {}
					//TODO change to info again
					Ti.API.info("Response was ["+typeof response+']: '+JSON.stringify(response))
					
					that.removeLoading()
					
					if (_.contains([200, 201], this.status)) {
	                    deferred.resolve(response)
	                }				    
			        else {
						Ti.API.error(response)
						deferred.reject(new Error('['+this.status+'] '+this.statusText+': '+response))
					}
				},
Example #11
0
		var userFound = function (user) {
            if (user) {
            	if (typeof user.id == 'string')
            		var id = user.id
            	else if (typeof user.id == 'object' && _.has(user.id, '$oid'))
            		var id = user.id['$oid']
            	else
            		Ti.API.error('Could not find ID for user during login! Got '+JSON.stringify(user))
            		
				Ti.App.Properties.setString('userId', id)
                var home = require('ui/common/windows/main/lists')()
                home.open()
            }
            else {
                alert(L('invalidLogin'))
            }
		}
Example #12
0
	mountUrl: function(collection, id, queryString) {
		//verifying parameters to make sure no one is empty
		if (!collection) throw { name: 'ArgumentError', message: 'collection not specified!' }
		id = id || null
		queryString = queryString || null
		
		if (queryString) {
            var qsParts = []
		    _.each(queryString, function(data, key) {
		    	if (typeof data == 'object' && _.keys(data).length == 0) return
		    	else {
		    		//TODO: this is not handling regular expressions correctly: JSON.stringify returns {}
		    		//for RegExp objects. They should be recursively filtered and handled separately 
					var encodedData = encodeURIComponent((key == 'q')? JSON.stringify(data) : data)        
		        	qsParts.push(key+'='+encodedData)
		        }
		    })
		    queryString = qsParts.join('&')
		}
		
		return this._URL({ collection: collection, id: id, queryString: queryString })
	},
Example #13
0
exports.createButton = function(properties) {
	return Ti.UI.createButton(_.defaults(properties || {}, {
		borderRadius: 10
	}))
}
Example #14
0
exports.createFieldLabel = function(properties) {
	return exports.createLabel(_.defaults(properties || {}, {
		color: color.label,
		font: { fontSize: 16 }
	}))	
}
Example #15
0
	
/**
 * @class Models.Group
 * @extends Models.Model
 * Implementation of "groups" collection.
 * Representation of a group of {@link Models.User users}, sharing expenses.
 * 
 * @constructor
 * Creates a Group object based on an ID or an Object with the fields
 * @param {String/Object} idOrProperties Group ID or object properties. If ID, does a {@link Models.Group#find};
 * 		if property, calls {@link Models.Model#setFields}
 * @param {Function} callback (optional) to be called after {@link Models.Group#find} or {@link Models.Model#setFields}
 */
function Group () {

}

var modelData = {
	COLLECTION: 'groups',
	fields: [
		'id',
		'name',
		'users',
		'lists'
	]
}

_.extend(Group, _.omit(Model, 'save', 'update'), modelData)
_.extend(Group.prototype, Model, modelData)

module.exports = Group
Example #16
0
			label: white,
			text: lightDarkGray,
			field: {
				bg: darkerGray,
				color: white,
				bgModal: darkGray
			}
		}
	break;
	
	case 'iPhone OS':
	case 'iPad OS':
	default:
		color = {
			bg: gray, //probably should be some kind of simple texture?
			bgOp: black,
			bgModal: darkerGray,
			label: lightDarkGray,
			text: lightDarkGray,
			field: {
				bg: white,
				color: lightDarkGray,
				bgModal: white
			}
		}
	break;
	
}

_.extend(exports, color)
Example #17
0
	makeRequest: function(collection, requestType, data, queryString) {
		if (!_.contains(this.REQUEST, requestType))
			throw { name: 'ArgumentError', message: 'request should be one of the Model.request constants.' }
		
		// ~~~~~~~~~~~~~~~~~~~~~~~~ setting the request verb ~~~~~~~~~~~~~~~~~~~~~~~~
		var verb
		switch (requestType) {
			case this.REQUEST.INSERT:	verb = 'POST';   break
			case this.REQUEST.FIND:		verb = 'GET';    break
			case this.REQUEST.UPDATE:
			case this.REQUEST.REPLACE:	verb = 'PUT';    break
			case this.REQUEST.DELETE:	verb = 'DELETE'; break	
		}
		
		// ~~~~~~~~~~~~~~~~~~~~~ setting request query and data ~~~~~~~~~~~~~~~~~~~~~
		var useId = null
		if (_.has(data, 'id')) {
			if (_.isEmpty(queryString)) {
				useId = data.id
				data = _.omit(data, 'id')
			}
			else {
				if (!_.isObject(queryString)) queryString = {}
				queryString.q = _.extend(queryString.q || {}, { _id: data.id })
			}
		}
		//empty objects are never needed by the API, but empty lists can be useful
		dataString = (!_.isArray(data) && _.isEmpty(data))? '' : JSON.stringify(data)
		
		// ~~~~~~~~~~~~~~~~~~~~~~~ setting the request headers ~~~~~~~~~~~~~~~~~~~~~~~
		var headers = {
			'X-Requested-With': null, //cleaning useless default header
			'Content-Type': 'application/json;charset=utf-8'
		}
		
		// ~~~~~~~~~~~~~~~~~~~~~~ setting up the actual request ~~~~~~~~~~~~~~~~~~~~~~
		var that = this,
			withLoading = false,
			deferred = Q.defer(),
			response,
			request = Ti.Network.createHTTPClient({
				timeout: this.TIMEOUT,
				//autoEncodeUrl: false, //TODO is this really needed?
				onload: function(source) {
					response = JSON.parse(this.responseText)
					if (response === null) response = {}
					//TODO change to info again
					Ti.API.info("Response was ["+typeof response+']: '+JSON.stringify(response))
					
					that.removeLoading()
					
					if (_.contains([200, 201], this.status)) {
	                    deferred.resolve(response)
	                }				    
			        else {
						Ti.API.error(response)
						deferred.reject(new Error('['+this.status+'] '+this.statusText+': '+response))
					}
				},
				
				onerror: function(error) {
					that.removeLoading()
					alert(L('unavailable'))
					Ti.API.error('MONGO ANSWERED ERROR '+this.status+': '+this.statusText)
					deferred.reject('['+this.status+'] '+this.statusText)
				}//,
				
				/*
				 * FIXME: Not working,  Ti.Network.HTTPClient.* are all undefined. Probably fixed in a
				 * newer SDK. Check back and remove the other calls to add/removeLoading()
				 * TODO: when this is done we should also include deferred.notify()
					onreadystatechange: function() {
						switch (this.readyState) {
							case Ti.Network.HTTPClient.UNSENT:
							case Ti.Network.HTTPClient.OPENED:
								that.addLoading()
							break
							
							case Ti.Network.HTTPClient.DONE:
								that.removeLoading()
							break
						}
					}
			   	*/
			})
			
		
		//TODO change to info again
		Ti.API.info('MONGO ['+verb+']: '+this.mountUrl(collection, useId, queryString))
		if (verb != 'GET' && verb != 'DELETE') Ti.API.info('Data sent: '+dataString)
		
		request.open(verb, this.mountUrl(collection, useId, queryString))

		_.each(headers, function(value, title) { request.setRequestHeader(title, value) })
		
		//a better place for this would be inside the onReadyStateChange callback method, but take a look
		//at the FIXME comment there... :(
		this.addLoading()
		
		request.send(dataString)
		
		return deferred.promise
	},
Example #18
0
/**
 * @class Models.User
 * @extends Models.Model
 * Implementation of "users" collection.
 * Representation of an app user in the database. Should have a {@link Models.Group}.
 * 
 * @constructor
 * Creates a User object based on an ID or an Object with the fields
 * @param {String/Object} idOrProperties User ID or object properties. If ID, does a {@link Models.User#find};
 * 		if property, calls {@link Models.Model#setFields}
 * @param {Function} callback (optional) to be called after {@link Models.User#find} or {@link Models.Model#setFields}
 */
function User () {
	
}

var modelData = {
	COLLECTION: 'users',
	fields: [
		'id',
		'name',
		'surname',
		'email',
		'password'
	]
}

_.extend(User, _.omit(Model, 'save', 'update'), modelData)
_.extend(User.prototype, Model, modelData)

module.exports = User
Example #19
0
 * ## Returned Status Codes
 * * 200 - Worked
 * * 201 - Created *(turns out that the 1.0 API don't return this code when a new entry is created; it does return 200)*
 * * 400 - Misformatted data
 * * 401 - Wrong credentials
 * * 403 - Denied permission
 * * 404 - Wrong URL
 * * 405 - Wrong verb
 * * 415 - Lack of header `Content-Type: application/json;charset=utf-8`
 * * 50X - Run to the hills! Mongolab crashed!! 
 */
module.exports = {
	/** Used internally to generate the final request URL
	 * @type {Function} 
	 * @private */
	_URL: _.template('https://api.mongolab.com/api/1/databases/marketshare/collections/<%=collection%>/<%=id%>?<%=queryString%>&apiKey='+config.API_KEY),
	
	/** Default timeout
	 * @protected */
	TIMEOUT: 5000,
	
	/** Constants for each type of Request the API should understand
	 * @private */
	REQUEST: {
		INSERT:  0,	//C
		FIND:    1,	//R
		UPDATE:  2,	//U
		REPLACE: 3,	//U
		DELETE:  4	//D
	},