Last active
December 30, 2015 09:29
-
-
Save vlucas/7810041 to your computer and use it in GitHub Desktop.
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
// "Constants" | |
exports.STYLE_HINT = 'hint'; | |
exports.STYLE_LABEL = 'label'; | |
exports.TYPE_DATE = 'date'; | |
exports.TYPE_DATETIME = 'datetime'; | |
exports.TYPE_EMAIL = 'email'; | |
exports.TYPE_URL = 'url'; | |
exports.TYPE_NUMBER = 'number'; | |
exports.TYPE_PASSWORD = 'password'; | |
exports.TYPE_PHONE = 'phone'; | |
exports.TYPE_BOOLEAN = 'boolean'; | |
exports.TYPE_PICKER = 'select'; | |
exports.TYPE_STRING = 'string'; | |
exports.TYPE_TEXT = 'text'; | |
exports.TYPE_FILE = 'file'; | |
exports.TYPE_SUBMIT = 'submit'; | |
var isAndroid = Ti.Platform.osname === 'android'; | |
var textFieldDefaults = { | |
height: '40dp', | |
top: '10dp', | |
color: '#222', | |
right : 0, | |
left : 0 | |
}; | |
var keyboardMap = {}; | |
keyboardMap[exports.TYPE_EMAIL] = Ti.UI.KEYBOARD_EMAIL; | |
keyboardMap[exports.TYPE_URL] = Ti.UI.KEYBOARD_URL; | |
keyboardMap[exports.TYPE_NUMBER] = Ti.UI.KEYBOARD_NUMBER_PAD; | |
keyboardMap[exports.TYPE_PASSWORD] = Ti.UI.KEYBOARD_DEFAULT; | |
keyboardMap[exports.TYPE_PHONE] = Ti.UI.KEYBOARD_NUMBER_PAD; | |
keyboardMap[exports.TYPE_TEXT] = Ti.UI.KEYBOARD_DEFAULT; | |
var handleStyle = function(form, field, textField, title) { | |
if (form.fieldStyle === exports.STYLE_HINT && textField) { | |
textField.hintText = title; | |
var noTouchFields = ['username', 'email', 'password', 'password_confirm', 'url', 'link_url']; | |
var autocorrectTypes = [exports.TYPE_STRING, exports.TYPE_TEXT]; | |
if(noTouchFields.indexOf(field.name) !== -1 || autocorrectTypes.indexOf(field.type) === -1) { | |
textField.autocorrect = false; | |
textField.autocapitalization = Titanium.UI.TEXT_AUTOCAPITALIZATION_NONE; | |
} | |
if(field.hasOwnProperty('length')) { | |
textField.maxLength = field.length; | |
} | |
} else { | |
form.container.add(Ti.UI.createLabel({ | |
text: title, | |
top: '10dp', | |
left: '35dp', | |
color: '#222', | |
font: { | |
fontSize: '16dp', | |
fontWeight: 'bold' | |
}, | |
height: 'auto', | |
width: 'auto' | |
})); | |
if (textField) { | |
textField.top = '5dp'; | |
} | |
} | |
}; | |
var setupPickerTextField = function(textField, pickerType, data) { | |
textField.editable = false; | |
textField.rightButton = Ti.UI.createButton({ | |
style: Ti.UI.iPhone.SystemButton.DISCLOSURE, | |
transform: Ti.UI.create2DMatrix().rotate(90) | |
}); | |
textField.rightButtonMode = Ti.UI.INPUT_BUTTONMODE_ALWAYS; | |
textField.addEventListener('click', function(e) { | |
e.source.blur(); | |
var semiModalPicker = require('/tin/semiModalPicker').createSemiModalPicker({ | |
textField: textField, | |
value: textField.value, | |
type: pickerType, | |
data: data | |
}); | |
if(isAndroid) { | |
semiModalPicker.open({ modal: true }); | |
} else { | |
semiModalPicker.open({ animated: false }); | |
} | |
}); | |
}; | |
var ctr = 1; | |
var addField = function(field, fieldRefs) { | |
var title = field.title || ('field' + ctr++); | |
var id = field.name || field.id || title; | |
var type = field.type || exports.TYPE_TEXT; | |
var form = this; | |
var fieldObject = undefined; | |
textFieldDefaults.value = field.value || null; | |
if ( | |
type === exports.TYPE_STRING || | |
type === exports.TYPE_URL || | |
type === exports.TYPE_EMAIL || | |
type === exports.TYPE_NUMBER || | |
type === exports.TYPE_PHONE || | |
type === exports.TYPE_PASSWORD) { | |
fieldObject = Ti.UI.createTextField(textFieldDefaults); | |
fieldObject._type = type; | |
fieldObject.keyboardType = keyboardMap[type]; | |
fieldObject.passwordMask = type === exports.TYPE_PASSWORD; | |
handleStyle(form, field, fieldObject, title); | |
} else if (type === exports.TYPE_TEXT) { | |
fieldObject = Ti.UI.createTextArea(textFieldDefaults); | |
fieldObject.height = '120dp'; | |
handleStyle(form, field, fieldObject, title); | |
} else if (type === exports.TYPE_BOOLEAN) { | |
fieldObject = Ti.UI.createSwitch({value:0}); | |
handleStyle(form, field, undefined, title); | |
} else if (type === exports.TYPE_DATE) { | |
if (isAndroid) { | |
// Titanium android does not support date picker, so we have to just display as a text field... (sigh) | |
fieldObject = Ti.UI.createTextField(textFieldDefaults); | |
handleStyle(form, field, fieldObject, title); | |
setupPickerTextField(fieldObject, Ti.UI.PICKER_TYPE_DATE); | |
} else { | |
fieldObject = Ti.UI.createTextField(textFieldDefaults); | |
handleStyle(form, field, fieldObject, title); | |
setupPickerTextField(fieldObject, Ti.UI.PICKER_TYPE_DATE); | |
} | |
} else if (type === exports.TYPE_DATETIME) { | |
if (isAndroid) { | |
// Titanium android does not support date+time picker, so we have to just display as a text field... (mega sigh) | |
fieldObject = Ti.UI.createTextField(textFieldDefaults); | |
handleStyle(form, field, fieldObject, title); | |
setupPickerTextField(fieldObject, Ti.UI.PICKER_TYPE_DATE); | |
} else { | |
fieldObject = Ti.UI.createTextField(textFieldDefaults); | |
handleStyle(form, field, fieldObject, title); | |
setupPickerTextField(fieldObject, Ti.UI.PICKER_TYPE_DATE_AND_TIME); | |
} | |
} else if (type === exports.TYPE_PICKER) { | |
if (isAndroid) { | |
// fieldObject = Ti.UI.createPicker({ | |
// type: Ti.UI.PICKER_TYPE_PLAIN, | |
// value: field.value | |
// }); | |
// handleStyle(form, field, undefined, title); | |
// for (var i in field.options) { | |
// var value = tin.isNumber(i) ? field.options[i] : i; | |
// fieldObject.add(Ti.UI.createPickerRow({ title:field.options[i], value: value })); | |
// } | |
fieldObject = Ti.UI.createTextField(textFieldDefaults); | |
handleStyle(form, field, fieldObject, title); | |
setupPickerTextField(fieldObject, Ti.UI.PICKER_TYPE_PLAIN, field.options); | |
} else { | |
fieldObject = Ti.UI.createTextField(textFieldDefaults); | |
handleStyle(form, field, fieldObject, title); | |
setupPickerTextField(fieldObject, Ti.UI.PICKER_TYPE_PLAIN, field.options); | |
} | |
} else if (type === exports.TYPE_FILE) { | |
var fieldObject = Ti.UI.createButton({ | |
title: 'Select Photo...', | |
top:'10dp' | |
}); | |
fieldObject.addEventListener('click', function(e) { | |
Ti.Media.openPhotoGallery({ | |
mediaTypes:[Ti.Media.MEDIA_TYPE_PHOTO], | |
success:function(e) { | |
fieldObject.value = e.media; | |
fieldObject.title = '[ Photo Selected ]'; | |
}, | |
cancel:function() { | |
fieldObject.value = null; | |
fieldObject.title = 'Select Photo...'; | |
}, | |
error:function(err) { | |
Ti.API.error(err); | |
fieldObject.value = null; | |
fieldObject.title = 'Select Photo...'; | |
} | |
}); | |
}); | |
} else if (type === exports.TYPE_SUBMIT) { | |
var button = Ti.UI.createButton({ | |
title: title, | |
top:'10dp' | |
}); | |
button.addEventListener('click', function(e) { | |
var values = {}; | |
for (var i in fieldRefs) { | |
values[i] = fieldRefs[i].value; | |
} | |
form.fireEvent(id, {values:values}); | |
}); | |
form.container.add(button); | |
} | |
// Add our prepared UI component to the form | |
if (fieldObject) { | |
form.container.add(fieldObject); | |
fieldRefs[id] = fieldObject; | |
} | |
}; | |
var addFields = function(fields, fieldRefs) { | |
for (var i in fields) { | |
this.addField(fields[i], fieldRefs); | |
} | |
}; | |
exports.createForm = function(o) { | |
var container = Ti.UI.createView({ | |
layout: 'vertical', | |
height: 'auto' | |
}); | |
var fieldRefs = {}; | |
var form = Ti.UI.createScrollView({ | |
contentHeight: 'auto', | |
contentWidth: 'auto', | |
showVerticalScrollIndicator:true, | |
showHorizontalScrollIndicator:true, | |
// new stuff | |
container: container, | |
fieldStyle: o.style || exports.STYLE_HINT, | |
addField: addField, | |
addFields: addFields | |
}); | |
form.addFields(o.fields, fieldRefs); | |
form.add(container); | |
// Add this so each field can be accessed directly, if necessary | |
form.fieldRefs = fieldRefs; | |
return form; | |
} |
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
var isAndroid = Ti.Platform.osname === 'android'; | |
// Helpers | |
var stringToDate = function(dateString) { | |
dateString = dateString || ''; | |
var matches = /(\d+)\/(\d+)\/(\d+)/.exec(dateString); | |
if (matches && matches.length >= 4) { | |
return new Date(matches[3], matches[1] - 1, matches[2]); | |
} | |
return new Date(); | |
}; | |
var stringToDateTime = function(dateString) { | |
dateString = dateString || ''; | |
var matches = /(\d+)\/(\d+)\/(\d+) (\d+):(\d+)/.exec(dateString); | |
if (matches && matches.length >= 4) { | |
return new Date(matches[3], matches[1] - 1, matches[2], matches[4], matches[5]); | |
} | |
return new Date(); | |
}; | |
var dateToString = function(date) { | |
return (date.getMonth()+1) + '/' + date.getDate() + '/' + date.getFullYear(); | |
}; | |
var dateTimeToString = function(date) { | |
return (date.getMonth()+1) + '/' + date.getDate() + '/' + date.getFullYear() + ' ' + date.getHours() + ':' + date.getMinutes(); | |
}; | |
var toType = function(me) { | |
return Object.prototype.toString.call(me).split(/\W/)[2].toLowerCase(); | |
}; | |
// Main method | |
exports.createSemiModalPicker = function(o) { | |
var type = o.type === undefined ? Ti.UI.PICKER_TYPE_PLAIN : o.type; | |
var modalWin = Ti.UI.createWindow({ | |
backgroundColor:'transparent' | |
}); | |
var overlay = Ti.UI.createView({ | |
backgroundColor: '#000', | |
opacity: 0.6 | |
}); | |
var container = Ti.UI.createView({ | |
bottom: 0, | |
layout: 'vertical', | |
height: '251dp' | |
}); | |
var picker = Ti.UI.createPicker({ | |
type: type, | |
height: 'auto', | |
selectionIndicator: true | |
}); | |
if (type === Ti.UI.PICKER_TYPE_DATE) { | |
picker.value = stringToDate(o.value); | |
} else if (type === Ti.UI.PICKER_TYPE_DATE_AND_TIME) { | |
picker.value = stringToDateTime(o.value); | |
} else if (o.data) { | |
for (var i in o.data) { | |
if(toType(o.data) === 'array') { | |
var value = o.data[i]; | |
} else { | |
var value = toType(i) === 'string' ? i : o.data[i]; | |
} | |
picker.add(Ti.UI.createPickerRow({ title: o.data[i], value: value })); | |
} | |
} | |
picker.addEventListener('change', function(e) {}); | |
// Toolbar UI | |
if(isAndroid) { | |
container.backgroundColor = '#ccc'; | |
var cancel = Ti.UI.createButton({ | |
title:'Cancel', | |
width: '80dp', | |
left: '10dp', | |
top: '3dp' | |
}); | |
var done = Ti.UI.createButton({ | |
title:'Done', | |
width: '80dp', | |
right: '10dp', | |
top: '3dp' | |
}); | |
var toolbar = Ti.UI.createView({ | |
height: '48dp', | |
backgroundColor: '#bbb' | |
}); | |
toolbar.add(cancel); | |
toolbar.add(done); | |
} else { | |
var cancel = Ti.UI.createButton({ | |
title:'Cancel', | |
style: Ti.UI.iPhone.SystemButtonStyle.BORDERED | |
}); | |
var done = Ti.UI.createButton({ | |
title:'Done', | |
style: Ti.UI.iPhone.SystemButtonStyle.DONE | |
}); | |
var spacer = Ti.UI.createButton({ | |
systemButton: Ti.UI.iPhone.SystemButton.FLEXIBLE_SPACE | |
}); | |
var toolbar = Ti.UI.iOS.createToolbar({ | |
top:0, | |
items: [cancel, spacer, done] | |
}); | |
} | |
// Events | |
cancel.addEventListener('click', function(e) { | |
modalWin.close(); | |
}); | |
done.addEventListener('click', function(e) { | |
if (type === Ti.UI.PICKER_TYPE_DATE) { | |
o.textField.value = dateToString(picker.value); | |
} else if (type === Ti.UI.PICKER_TYPE_DATE_AND_TIME) { | |
o.textField.value = dateTimeToString(picker.value); | |
} else { | |
o.textField.value = picker.getSelectedRow(0).value || picker.getSelectedRow(0).title; | |
} | |
modalWin.close(); | |
}); | |
container.add(toolbar); | |
container.add(picker); | |
modalWin.add(overlay); | |
modalWin.add(container); | |
return modalWin; | |
}; |
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
var forms = require('/lib/forms'); | |
fields = []; | |
fields.push({title: 'Name', type: 'text', id: 'name' }); | |
fields.push({title: 'Submit', type: 'submit', id: 'submit' }); | |
var formWin = Ti.UI.createWindow(); | |
// Setup form | |
var form = forms.createForm({ | |
style: forms.STYLE_HINT, | |
fields: fields, | |
window: formWin | |
}); | |
formWin.addEventListener('open', function(e) { | |
// Focus on first form field | |
var firstField = _.first(fields); | |
var firstFieldObj = form.fieldRefs[firstField.name || firstField.id]; | |
if(firstFieldObj) { | |
firstFieldObj.focus(); | |
} | |
}); | |
form.addEventListener('submit', function(e) { | |
// Handle form submit | |
}); | |
// Add form to window | |
formWin.add(form); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment