assets/js/romo/form.js in romo-0.19.10 vs assets/js/romo/form.js in romo-0.20.0
- old
+ new
@@ -1,231 +1,287 @@
-$.fn.romoForm = function(givenSubmitElement, givenIndicatorElements) {
- return $.map(this, function(element) {
- return new RomoForm(element, givenSubmitElement, givenIndicatorElements);
- });
-}
+var RomoForm = RomoComponent(function(elem, givenSubmitElems, givenSpinnerElems) {
+ this.elem = elem;
-var RomoForm = function(element, givenSubmitElement, givenIndicatorElements) {
- this.elem = $(element);
- this.defaultSubmitElem = this.elem.find('button[type="submit"], input[type="submit"], [data-romo-form-submit]');
- this.submitElem = $(givenSubmitElement || this.defaultSubmitElem);
- this.defaultIndicatorElems = this.elem.find('[data-romo-indicator-auto="true"]');
- this.indicatorElems = $(givenIndicatorElements || this.defaultIndicatorElems);
- this.changeSubmitElems = this.elem.find('[data-romo-form-change-submit="true"]');
- this.onkeySubmitElems = this.elem.find('[data-romo-form-onkey-submit="true"]');
+ var defaultSubmitElems = Romo.find(
+ this.elem,
+ 'button[type="submit"], input[type="submit"], [data-romo-form-submit]'
+ );
+ this.submitElems = (givenSubmitElems || []).concat(defaultSubmitElems || []);
- this.defaultListValuesDelim = ',';
+ var defaultSpinnerElems = Romo.find(this.elem, '[data-romo-spinner-auto="true"]');
+ this.spinnerElems = (givenSpinnerElems || []).concat(defaultSpinnerElems || []);
+
+ this.changeSubmitElems = Romo.find(this.elem, '[data-romo-form-change-submit="true"]');
+ this.onkeySubmitElems = Romo.find(this.elem, '[data-romo-form-onkey-submit="true"]');
+
+ this.defaultListValuesDelim = ',';
this.onkeyDefaultSubmitDelay = 300; // 0.3 secs
- this.submitQueued = false;
- this.submitRunning = false;
+ this.submitQueued = false;
+ this.submitRunning = false;
- this.removeEmptyGetParams = this.elem.data('romo-form-remove-empty-get-params')
+ this.removeEmptyGetParams = Romo.data(this.elem, 'romo-form-remove-empty-get-params');
if (this.removeEmptyGetParams === undefined) {
this.removeEmptyGetParams = true;
}
- this.decodeParams = this.elem.data('romo-form-decode-params')
+ this.decodeParams = Romo.data(this.elem, 'romo-form-decode-params');
if (this.decodeParams === undefined) {
this.decodeParams = true;
}
this.doInit();
- this.doBindForm();
- this.elem.trigger('form:clearMsgs', [this]);
- this.elem.trigger('form:ready', [this]);
-}
+ this._bindElem();
-RomoForm.prototype.doInit = function() {
- // override as needed
-}
+ Romo.trigger(this.elem, 'romoForm:clearMsgs', [this]);
+ Romo.trigger(this.elem, 'romoForm:ready', [this]);
+});
-RomoForm.prototype.doBindForm = function() {
- this.defaultSubmitElem.unbind('click');
- this.submitElem.unbind('click');
- this.submitElem.on('click', $.proxy(this.onSubmitClick, this));
-
- this.changeSubmitElems.on('change', $.proxy(function(e) {
- this.elem.trigger('form:triggerSubmit');
- }, this));
- this.onkeySubmitElems.on('onkey:trigger', $.proxy(function(e, triggerEvent, onkey) {
- clearTimeout(this.onkeySubmitTimeout);
- this.onkeySubmitTimeout = setTimeout($.proxy(function() {
- this.elem.trigger('form:triggerSubmit');
- }, this), onkey.elem.data('romo-form-onkey-submit-delay') || this.onkeyDefaultSubmitDelay);
- }, this));
- this.elem.on('form:triggerSubmit', $.proxy(this.onSubmitClick, this));
-
- this.elem.on('keypress', $.proxy(this.onFormKeyPress, this));
-
- if (this.elem.data('romo-form-reload-page') === true) {
- this.elem.on('form:submitSuccess', function(e, data, form) {
- Romo.reloadPage();
- })
- }
-
-}
-
-RomoForm.prototype.onFormKeyPress = function(e) {
- if (this.elem.data('romo-form-disable-keypress') !== true) {
- var targetElem = $(e.target);
- if (targetElem.is(':not(TEXTAREA)') && e.keyCode === 13 /* Enter */) {
- e.preventDefault();
- if (this.elem.data('romo-form-disable-enter-submit') !== true &&
- targetElem.data('romo-form-disable-enter-submit') !== true) {
- this.onSubmitClick();
- }
- }
- }
-}
-
-RomoForm.prototype.onSubmitClick = function(e) {
- if (e !== undefined) {
- e.preventDefault();
- }
-
- if (this.submitElem.data('romo-form-submit') === 'confirm') {
- this.elem.trigger('form:confirmSubmit', [this]);
- } else if (this.submitElem.hasClass('disabled') === false) {
- this.doSubmit();
- }
-}
-
RomoForm.prototype.doSubmit = function() {
this.submitQueued = true;
if (this.submitRunning === false) {
- this._doSubmit();
+ this._submit();
}
}
-RomoForm.prototype.onSubmitSuccess = function(data, status, xhr) {
- this.elem.trigger('form:clearMsgs');
- this.elem.trigger('form:submitSuccess', [data, this]);
- this._doCompleteSubmit();
-}
+// private
-RomoForm.prototype.onSubmitError = function(xhr, errorType, error) {
- this.elem.trigger('form:clearMsgs');
+RomoForm.prototype._bindElem = function() {
+ Romo.on(this.submitElems, 'click', Romo.proxy(this._onSubmitClick, this));
- if(xhr.status === 422) {
- this.elem.trigger('form:submitInvalidMsgs', [$.parseJSON(xhr.responseText), xhr, this]);
- } else {
- this.elem.trigger('form:submitXhrError', [xhr, this]);
- }
- this.elem.trigger('form:submitError', [xhr, this]);
- this.indicatorElems.trigger('indicator:triggerStop');
- this._doCompleteSubmit();
-}
+ Romo.on(this.changeSubmitElems, 'change', Romo.proxy(function(e) {
+ Romo.trigger(this.elem, 'romoForm:triggerSubmit');
+ }, this));
-// private
+ Romo.on(this.onkeySubmitElems, 'romoOnkey:trigger', Romo.proxy(function(e, triggerEvent, romoOnkey) {
+ Romo.trigger(this.elem, 'romoForm:triggerSubmit');
+ }, this));
-RomoForm.prototype._doCompleteSubmit = function() {
- this.elem.trigger('form:submitComplete', [this]);
- if (this.submitQueued === true) {
- this._doSubmit();
- } else {
- this.submitRunning = false;
+ Romo.on(this.elem, 'romoForm:triggerSubmit', Romo.proxy(this._onTriggerSubmit, this));
+ Romo.on(this.elem, 'keypress', Romo.proxy(this._onFormKeyPress, this));
+
+ if (Romo.data(this.elem, 'romo-form-reload-page') === true) {
+ Romo.on(this.elem, 'romoForm:submitSuccess', function(e, data, romoForm) {
+ Romo.reloadPage();
+ });
}
}
-RomoForm.prototype._doSubmit = function() {
+RomoForm.prototype._submit = function() {
this.submitQueued = false;
this.submitRunning = true;
- this.indicatorElems.trigger('indicator:triggerStart');
- this.elem.trigger('form:beforeSubmit', [this]);
- if(this.elem.data('romo-form-browser-submit') === true) {
- this._doBrowserSubmit();
- } else if (this.elem.attr('method').toUpperCase() === 'GET') {
- this._doNonBrowserGetSubmit();
+ Romo.trigger(this.spinnerElems, 'romoSpinner:triggerStart');
+ Romo.trigger(this.elem, 'romoForm:beforeSubmit', [this]);
+
+ if(Romo.data(this.elem, 'romo-form-browser-submit') === true) {
+ this._browserSubmit();
+ } else if (Romo.attr(this.elem, 'method').toUpperCase() === 'GET') {
+ this._nonBrowserGetSubmit();
} else {
- this._doNonBrowserNonGetSubmit();
+ this._nonBrowserNonGetSubmit();
}
}
-RomoForm.prototype._doBrowserSubmit = function() {
+RomoForm.prototype._browserSubmit = function() {
this.elem.submit();
- this.elem.trigger('form:browserSubmit', [this]);
+ Romo.trigger(this.elem, 'romoForm:browserSubmit', [this]);
}
-RomoForm.prototype._doNonBrowserGetSubmit = function() {
- var data = this._getSerializeObj();
+RomoForm.prototype._nonBrowserGetSubmit = function() {
+ var formValues = this._getFormValues({ includeFiles: false });
- if (this.elem.data('romo-form-redirect-page') === true) {
- var paramString = Romo.param(data, {
+ if (Romo.data(this.elem, 'romo-form-redirect-page') === true) {
+ var paramString = Romo.param(formValues, {
removeEmpty: this.removeEmptyGetParams,
decodeValues: this.decodeParams
});
if (paramString !== '') {
- Romo.redirectPage(this.elem.attr('action') + '?' + paramString);
+ Romo.redirectPage(Romo.attr(this.elem, 'action')+'?'+paramString);
} else {
- Romo.redirectPage(this.elem.attr('action'));
+ Romo.redirectPage(Romo.attr(this.elem, 'action'));
}
-
} else {
- this._doAjaxSubmit(data, true);
+ this._ajaxSubmit(formValues);
}
}
-RomoForm.prototype._doNonBrowserNonGetSubmit = function() {
- this._doAjaxSubmit(this._getFormData(), false);
+RomoForm.prototype._nonBrowserNonGetSubmit = function() {
+ var formValues = this._getFormValues({ includeFiles: true });
+
+ this._ajaxSubmit(formValues);
}
-RomoForm.prototype._doAjaxSubmit = function(data, process) {
- $.ajax({
- url: this.elem.attr('action'),
- type: this.elem.attr('method'),
- dataType: this._getXhrDataType(),
- data: data,
- processData: process,
- contentType: false,
- success: $.proxy(this.onSubmitSuccess, this),
- error: $.proxy(this.onSubmitError, this)
+RomoForm.prototype._ajaxSubmit = function(formValues) {
+ Romo.ajax({
+ url: Romo.attr(this.elem, 'action'),
+ type: Romo.attr(this.elem, 'method'),
+ data: formValues,
+ success: Romo.proxy(this._onSubmitSuccess, this),
+ error: Romo.proxy(this._onSubmitError, this)
});
}
-RomoForm.prototype._getFormData = function() {
- var formData = new FormData();
- $.each(this._getSerializeObj(), function(k, v){ formData.append(k, v) });
- $.each(this.elem.find('INPUT[type="file"]'), function(i, fileInput) {
- var attrName = $(fileInput).attr('name')
- $.each(fileInput.files, function(i, file) { formData.append(attrName, file) });
+RomoForm.prototype._completeSubmit = function() {
+ Romo.trigger(this.elem, 'romoForm:submitComplete', [this]);
+ if (this.submitQueued === true) {
+ this._submit();
+ } else {
+ this.submitRunning = false;
+ }
+}
+
+RomoForm.prototype._getFormValues = function(opts) {
+ if (opts === undefined) {
+ opts = { includeFiles: false };
+ }
+ var formValues = {};
+
+ // build formValues from the form elements
+ // { "inputName1": ["inputValue1"],
+ // "inputName2": ["inputValue1", "inputValue2"],
+ // ...
+ // }
+ Romo.array(this.elem.elements).forEach(function(inputElem) {
+ if ( inputElem.nodeName.toLowerCase() !== 'fieldset' &&
+ inputElem.name &&
+ !inputElem.disabled &&
+ inputElem.type !== 'submit' &&
+ inputElem.type !== 'reset' &&
+ inputElem.type !== 'button' &&
+ (opts.includeFiles || inputElem.type !== 'file') &&
+ (inputElem.checked || (inputElem.type !== 'radio' && inputElem.type !== 'checkbox'))
+ ) {
+ if (formValues[inputElem.name] === undefined) {
+ formValues[inputElem.name] = [];
+ }
+ if (inputElem.nodeName.toLowerCase() === 'select') {
+ Romo.find(inputElem, 'option').filter(function(optElem){
+ return optElem.selected;
+ }).forEach(function(selectedOptElem) {
+ formValues[inputElem.name].push(selectedOptElem.value);
+ });
+ } else if (inputElem.type === 'file') {
+ Array.prototype.forEach.call(inputElem.files, function(file) {
+ formValues[inputElem.name].push(file);
+ });
+ } else {
+ formValues[inputElem.name].push(inputElem.value);
+ }
+ }
});
- return formData;
+ // process any list value inputs (if any)
+ // { inputName1: ["inputValue1"],
+ // inputName2: ["inputValue1,inputValue2"],
+ // ...
+ // }
+ var listDelims = Romo.find(this.elem, '[data-romo-form-list-values="true"]').reduce(
+ function(delims, inputElem) {
+ delims[Romo.attr(inputElem, 'name')] = (
+ Romo.data(inputElem, 'romo-form-list-values-delim') ||
+ this.defaultListValuesDelim
+ );
+ return delims;
+ },
+ {}
+ );
+ for (var name in listDelims) {
+ if (formValues[name]) {
+ formValues[name] = [formValues[name].join(listDelims[name])];
+ }
+ }
+
+ // remove the array from any single item array values
+ for(var key in formValues) {
+ if (formValues[key].length === 1) {
+ formValues[key] = formValues[key][0]
+ }
+ }
+
+ return formValues;
}
-RomoForm.prototype._getSerializeObj = function() {
- var listNamesDelims = this._getListValueInputNamesDelims();
+RomoForm.prototype._getXhrDataType = function() {
+ var dataType = Romo.data(this.elem, 'romo-form-xhr-data-type');
+ return ((dataType === undefined) ? 'json' : dataType);
+}
- return this.elem.serializeArray().reduce(function(prev, curr) {
- if (listNamesDelims[curr.name] !== undefined) {
- prev[curr.name] = $.map([prev[curr.name], curr.value], function(v) {
- return v; // $.map removes null/undefined vals, this acts like a compact function
- }).join(listNamesDelims[curr.name])
+// event functions
+
+RomoForm.prototype.romoEvFn._onSubmitClick = function(e) {
+ e.preventDefault();
+
+ var submitElem = e.target;
+ if (!Romo.hasClass(submitElem, 'disabled')) {
+ if (Romo.data(submitElem, 'romo-form-submit') === 'confirm') {
+ Romo.trigger(this.elem, 'romoForm:confirmSubmit', [this]);
} else {
- prev[curr.name] = curr.value;
+ this.doSubmit();
}
+ }
+}
- return prev;
- }, {});
+RomoForm.prototype.romoEvFn._onTriggerSubmit = function() {
+ var disabled = this.submitElems.reduce(function(disabled, submitElem) {
+ return disabled || Romo.hasClass(submitElem, 'disabled');
+ }, false);
+ if (!disabled) {
+ var confirm = this.submitElems.reduce(function(confirm, submitElem) {
+ return confirm || Romo.data(submitElem, 'romo-form-submit') === 'confirm';
+ }, false);
+ if (confirm) {
+ Romo.trigger(this.elem, 'romoForm:confirmSubmit', [this]);
+ } else {
+ this.doSubmit();
+ }
+ }
}
-RomoForm.prototype._getListValueInputNamesDelims = function() {
- return Romo.toArray(this.elem.find('[data-romo-form-list-values="true"]')).reduce($.proxy(function(prev, curr) {
- prev[$(curr).attr('name')] = $(curr).data('romo-form-list-values-delim') || this.defaultListValuesDelim;
- return prev;
- }, this), {});
+RomoForm.prototype.romoEvFn._onFormKeyPress = function(e) {
+ if (Romo.data(this.elem, 'romo-form-disable-keypress') !== true) {
+ var targetElem = e.target;
+ if (targetElem.nodeName.toLowerCase() !== 'textarea' && e.keyCode === 13 /* Enter */) {
+ e.preventDefault();
+ if (Romo.data(this.elem, 'romo-form-disable-enter-submit') !== true &&
+ Romo.data(targetElem, 'romo-form-disable-enter-submit') !== true) {
+ this._onTriggerSubmit();
+ }
+ }
+ }
}
-RomoForm.prototype._getXhrDataType = function() {
- if(this.elem.data('romo-form-xhr-data-type') !== undefined) {
- return this.elem.data('romo-form-xhr-data-type');
+RomoForm.prototype.romoEvFn._onSubmitSuccess = function(response, status, xhr) {
+ Romo.trigger(this.elem, 'romoForm:clearMsgs');
+
+ var dataType = this._getXhrDataType();
+ Romo.trigger(
+ this.elem,
+ 'romoForm:submitSuccess',
+ [(dataType === 'json' ? JSON.parse(response) : response), this]
+ );
+
+ this._completeSubmit();
+}
+
+RomoForm.prototype.romoEvFn._onSubmitError = function(statusText, status, xhr) {
+ Romo.trigger(this.elem, 'romoForm:clearMsgs');
+
+ if(status === 422) {
+ var dataType = this._getXhrDataType();
+ Romo.trigger(
+ this.elem,
+ 'romoForm:submitInvalidMsgs',
+ [(dataType === 'json' ? JSON.parse(xhr.responseText) : xhr.responseText), xhr, this]
+ );
} else {
- return 'json';
+ Romo.trigger(this.elem, 'romoForm:submitXhrError', [xhr, this]);
}
+ Romo.trigger(this.elem, 'romoForm:submitError', [xhr, this]);
+ Romo.trigger(this.spinnerElems, 'romoSpinner:triggerStop');
+
+ this._completeSubmit();
}
-Romo.onInitUI(function(e) {
- Romo.initUIElems(e, '[data-romo-form-auto="true"]').romoForm();
-});
+// init
+Romo.addElemsInitSelector('[data-romo-form-auto="true"]', RomoForm);