From 6cebff7e13cf65237feb37f61bffb06f4081b3cf Mon Sep 17 00:00:00 2001 From: Sebastian Klaus Date: Thu, 14 Jan 2021 09:23:51 +0100 Subject: [PATCH 1/6] Update package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c52125f..cef44ea 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ti.growingform", - "version": "1.4.0", + "version": "1.5.0", "description": "A growing (\"stepper\") form for Appcelerator Titanium.", "main": "index.js", "scripts": { From 9cc2e95cb2b88ad78c25b554a397ec89ab163291 Mon Sep 17 00:00:00 2001 From: Sebastian Klaus Date: Thu, 14 Jan 2021 09:24:12 +0100 Subject: [PATCH 2/6] Update index.js --- index.js | 83 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 16 deletions(-) diff --git a/index.js b/index.js index 1de1689..619a323 100644 --- a/index.js +++ b/index.js @@ -167,6 +167,7 @@ class GrowingForm { // If the last element was a text-field, blur it! if (( this.cells[this.expandedIndex].type === GrowingFormFieldType.TEXT + || this.cells[this.expandedIndex].type === GrowingFormFieldType.TEXTAREA || this.cells[this.expandedIndex].type === GrowingFormFieldType.EMAIL || this.cells[this.expandedIndex].type === GrowingFormFieldType.NUMBER ) && this.currentTextField) { @@ -218,6 +219,9 @@ class GrowingForm { let textField; let actionButton; + const actionButtonOpacityValid = 1.0; + const actionButtonOpacityInvalid = 0.3; + // The container view holds both the content-view and bullets const containerView = Ti.UI.createView({ height: Ti.UI.SIZE, @@ -236,30 +240,39 @@ class GrowingForm { contentView.add(this._createTitleLabel(cell, itemIndex)); + const validation = isValid => { + this.formData[cell.identifier] = textField.value; + + // If we use live-validation, do not update our UI so far + if (cell.validate === GrowingFormValidationRule.LIVE) { + const throttle = cell.throttle; + if (!throttle || typeof throttle !== 'function') { + throw new FormError('using live validation without padding \'throttle\' method'); + } + throttle(textField, actionButton); + return; + } + + actionButton.opacity = isValid ? actionButtonOpacityValid : actionButtonOpacityInvalid; + actionButton.enabled = isValid; + } + // Only add content if expanded if (isExpanded) { switch (type) { + case GrowingFormFieldType.TEXTAREA: + textField = this._createTextArea({ + cell: cell, + onChange: validation + }); + contentView.add(textField); + break; case GrowingFormFieldType.TEXT: case GrowingFormFieldType.EMAIL: case GrowingFormFieldType.NUMBER: { textField = this._createTextField({ cell: cell, - onChange: isValid => { - this.formData[cell.identifier] = textField.value; - - // If we use live-validation, do not update our UI so far - if (cell.validate === GrowingFormValidationRule.LIVE) { - const throttle = cell.throttle; - if (!throttle || typeof throttle !== 'function') { - throw new FormError('using live validation without padding \'throttle\' method'); - } - throttle(textField, actionButton); - return; - } - - actionButton.opacity = isValid ? 1.0 : 0.3; - actionButton.enabled = isValid; - } + onChange: validation }); contentView.add(textField); break; @@ -358,6 +371,43 @@ class GrowingForm { this._configureData(); } + _createTextArea(args) { + const cell = args.cell; + const onChangeCallback = args.onChange; + const identifier = cell.identifier; + const validate = cell.validate; + const options = cell.options || {}; + + const textArea = Ti.UI.createTextArea({ + top: 8, + left: 0, + width: 280, + height: 120, + color: '#000', + hintTextColor: '#bebebe', + padding: { left: 5, right: 5 }, + borderRadius: 4, + backgroundColor: '#eee', + value: this.formData[identifier] || '' + }); + + // Reference a reference in our scope to blur it, if it is the last form input + this.currentTextField = textArea; + textArea.applyProperties(options); + + textArea.addEventListener('change', event => { + const value = event.value; + + // Check if we have a validator + if (validate !== undefined) { + const isValid = this._validateFromType(cell, value); + onChangeCallback(isValid); + } + }); + + return textArea; + } + _createTextField(args) { const cell = args.cell; const onChangeCallback = args.onChange; @@ -524,6 +574,7 @@ class GrowingForm { const GrowingFormFieldType = { TEXT: 'text', + TEXTAREA: 'textarea', EMAIL: 'email', NUMBER: 'number', CHECKBOX: 'checkbox', From bba5fb8c7d0db582e19b55672913ccd114e09f74 Mon Sep 17 00:00:00 2001 From: Sebastian Klaus Date: Thu, 14 Jan 2021 10:49:22 +0100 Subject: [PATCH 3/6] Update index.js --- index.js | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/index.js b/index.js index 619a323..913b779 100644 --- a/index.js +++ b/index.js @@ -165,12 +165,8 @@ class GrowingForm { } // If the last element was a text-field, blur it! - if (( - this.cells[this.expandedIndex].type === GrowingFormFieldType.TEXT - || this.cells[this.expandedIndex].type === GrowingFormFieldType.TEXTAREA - || this.cells[this.expandedIndex].type === GrowingFormFieldType.EMAIL - || this.cells[this.expandedIndex].type === GrowingFormFieldType.NUMBER - ) && this.currentTextField) { + if ((this.cells[this.expandedIndex].type === GrowingFormFieldType.TEXT + || this.cells[this.expandedIndex].type === GrowingFormFieldType.TEXTAREA) && this.currentTextField) { this.currentTextField.blur(); } if (this.callbacks[GrowingFormEvent.SUBMIT]) { @@ -267,9 +263,7 @@ class GrowingForm { }); contentView.add(textField); break; - case GrowingFormFieldType.TEXT: - case GrowingFormFieldType.EMAIL: - case GrowingFormFieldType.NUMBER: { + case GrowingFormFieldType.TEXT: { textField = this._createTextField({ cell: cell, onChange: validation @@ -364,6 +358,17 @@ class GrowingForm { const cell = this.cells[this.expandedIndex]; const value = this.formData[cell.identifier]; + if (this.cells[this.expandedIndex].type === GrowingFormFieldType.TEXT + || this.cells[this.expandedIndex].type === GrowingFormFieldType.TEXTAREA) { + console.log('drin'); + if (this.options.focusNexField === true) { + console.log('dran'); + setTimeout(() => { + this.focus(); + }, 200); + } + } + this.callbacks[GrowingFormEvent.STEP](this.currentTextField, this.expandedIndex + 1, this._validateFromType(cell, value)); } @@ -379,13 +384,14 @@ class GrowingForm { const options = cell.options || {}; const textArea = Ti.UI.createTextArea({ + id: identifier, top: 8, left: 0, width: 280, height: 120, color: '#000', hintTextColor: '#bebebe', - padding: { left: 5, right: 5 }, + padding: { left: 5, right: 5, top: 5, bottom: 5 }, borderRadius: 4, backgroundColor: '#eee', value: this.formData[identifier] || '' @@ -416,6 +422,7 @@ class GrowingForm { const options = cell.options || {}; const textField = Ti.UI.createTextField({ + id: identifier, top: 8, left: 0, width: 280, @@ -428,19 +435,6 @@ class GrowingForm { value: this.formData[identifier] || '' }); - switch (cell.type) { - case GrowingFormFieldType.NUMBER: - textField.keyboardType = Ti.UI.KEYBOARD_TYPE_NUMBER_PAD; - break; - case GrowingFormFieldType.EMAIL: - textField.autocapitalization = Ti.UI.TEXT_AUTOCAPITALIZATION_NONE - textField.keyboardType = Ti.UI.KEYBOARD_TYPE_EMAIL; - break; - default: - textField.keyboardType = Ti.UI.KEYBOARD_TYPE_DEFAULT; - break; - } - // Reference a reference in our scope to blur it, if it is the last form input this.currentTextField = textField; textField.applyProperties(options); @@ -575,8 +569,6 @@ class GrowingForm { const GrowingFormFieldType = { TEXT: 'text', TEXTAREA: 'textarea', - EMAIL: 'email', - NUMBER: 'number', CHECKBOX: 'checkbox', DROPDOWN: 'dropdown' }; From 9685c0b57f54fc61750a6ef4dfa1622656a62a00 Mon Sep 17 00:00:00 2001 From: Sebastian Klaus Date: Thu, 14 Jan 2021 10:51:36 +0100 Subject: [PATCH 4/6] Update index.js Field types are superfluous, as they can be controlled via keyboardType. Camel case textArea Auto-focus next field via option focusNexField: true --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 913b779..2628e2c 100644 --- a/index.js +++ b/index.js @@ -568,7 +568,7 @@ class GrowingForm { const GrowingFormFieldType = { TEXT: 'text', - TEXTAREA: 'textarea', + TEXTAREA: 'textArea', CHECKBOX: 'checkbox', DROPDOWN: 'dropdown' }; From 8d54a200597c3fdda4d06993b3325e3d56c2cb43 Mon Sep 17 00:00:00 2001 From: Sebastian Klaus Date: Thu, 14 Jan 2021 10:54:12 +0100 Subject: [PATCH 5/6] Update README.md --- README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bf546ac..30a9a44 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,22 @@ const config = { passwordMask: true, hintText: 'Enter password ...' } - }], + },{ + title: 'Comment', + identifier: 'comment', + type: GrowingFormFieldType.TEXTAREA, + validate: GrowingFormValidationRule.ALLOW_EMPTY, + options: { + suppressReturn: false, + font: { + fontSize: 14 + } + } + }], options: { + // Automatically focus next field + focusNexField: true, + // Style the underlaying table-view via it's header-view tableTopMargin: 50, From f8a730ae41ea2bdbeb2496d7fc38be23b211166e Mon Sep 17 00:00:00 2001 From: Sebastian Klaus Date: Thu, 14 Jan 2021 11:05:50 +0100 Subject: [PATCH 6/6] Update index.js added 'return' listener for textfields for quicker input --- index.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 2628e2c..6971c9c 100644 --- a/index.js +++ b/index.js @@ -360,9 +360,7 @@ class GrowingForm { if (this.cells[this.expandedIndex].type === GrowingFormFieldType.TEXT || this.cells[this.expandedIndex].type === GrowingFormFieldType.TEXTAREA) { - console.log('drin'); if (this.options.focusNexField === true) { - console.log('dran'); setTimeout(() => { this.focus(); }, 200); @@ -449,6 +447,21 @@ class GrowingForm { } }); + textField.addEventListener('return', event => { + const value = event.value; + + // Check if we have a validator + if (validate !== undefined) { + const isValid = this._validateFromType(cell, value); + console.log('isValid', isValid); + if (isValid === true) { + this._selectNextCell(); + } + return; + } + this._selectNextCell(); + }); + return textField; }