mirror of
https://github.com/Karaka-Management/jsOMS.git
synced 2026-01-11 09:58:39 +00:00
391 lines
9.3 KiB
JavaScript
391 lines
9.3 KiB
JavaScript
/**
|
|
* Form view.
|
|
*
|
|
* The form view contains a single form and it's data elements. Form actions are no longer handled by
|
|
* the browser but through this view. The view also provides additional functionality for non-default
|
|
* form elements such as canvas etc.
|
|
*
|
|
* @copyright Dennis Eichhorn
|
|
* @license OMS License 1.0
|
|
* @version 1.0.0
|
|
* @since 1.0.0
|
|
*/
|
|
(function (jsOMS)
|
|
{
|
|
"use strict";
|
|
/** @namespace jsOMS.Views */
|
|
jsOMS.Autoloader.defineNamespace('jsOMS.Views');
|
|
|
|
jsOMS.Views.FormView = class {
|
|
/**
|
|
* @constructor
|
|
*
|
|
* @param {string} id Form id
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
constructor (id)
|
|
{
|
|
this.id = id;
|
|
|
|
this.initializeMembers();
|
|
this.bind();
|
|
|
|
this.success = null;
|
|
this.lastSubmit = 0;
|
|
};
|
|
|
|
/**
|
|
* Initialize members
|
|
*
|
|
* Pulled out since this is used in a cleanup process
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
initializeMembers ()
|
|
{
|
|
this.submitInjects = [];
|
|
this.method = 'POST';
|
|
this.action = '';
|
|
};
|
|
|
|
/**
|
|
* Get method
|
|
*
|
|
* @return {string}
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
getMethod ()
|
|
{
|
|
return this.method;
|
|
};
|
|
|
|
/**
|
|
* Get action
|
|
*
|
|
* @return {string}
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
getAction ()
|
|
{
|
|
return this.action;
|
|
};
|
|
|
|
getLastSubmit ()
|
|
{
|
|
return this.lastSubmit;
|
|
};
|
|
|
|
updateLastSubmit ()
|
|
{
|
|
this.lastSubmit = Math.floor(Date.now());
|
|
};
|
|
|
|
/**
|
|
* Get submit elements
|
|
*
|
|
* @return {Object}
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
getSubmit ()
|
|
{
|
|
return document.querySelectorAll('#' + this.id + ' input[type=submit], button[form=' + this.id + '][type=submit], #' + this.id + ' button[type=submit]');
|
|
};
|
|
|
|
/**
|
|
* Get success callback
|
|
*
|
|
* @return {callback}
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
getSuccess ()
|
|
{
|
|
return this.success;
|
|
};
|
|
|
|
/**
|
|
* Set success callback
|
|
*
|
|
* @param {callback} callback Callback
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
setSuccess (callback)
|
|
{
|
|
this.success = callback;
|
|
};
|
|
|
|
/**
|
|
* Inject submit with post callback
|
|
*
|
|
* @param {callback} callback Callback
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
injectSubmit (callback)
|
|
{
|
|
this.submitInjects.push(callback);
|
|
};
|
|
|
|
/**
|
|
* Get form elements
|
|
*
|
|
* @return {Array}
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
getFormElements ()
|
|
{
|
|
const form = document.getElementById(this.id);
|
|
|
|
if (!form) {
|
|
return [];
|
|
}
|
|
|
|
const selects = form.getElementsByTagName('select'),
|
|
textareas = form.getElementsByTagName('textarea'),
|
|
inputs = [].slice.call(form.getElementsByTagName('input')),
|
|
canvas = form.getElementsByTagName('canvas'),
|
|
external = document.querySelectorAll('[form=' + this.id + ']'),
|
|
inputLength = inputs.length;
|
|
|
|
for (let i = 0; i < inputLength; ++i) {
|
|
if (inputs[i].type === 'checkbox' && !inputs[i].checked) {
|
|
delete inputs[i];
|
|
}
|
|
|
|
// todo: handle radio here as well
|
|
}
|
|
|
|
return this.getUniqueFormElements(
|
|
Array.prototype.slice.call(inputs).concat(
|
|
Array.prototype.slice.call(selects),
|
|
Array.prototype.slice.call(textareas),
|
|
Array.prototype.slice.call(external)
|
|
)
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Get unique form elements
|
|
*
|
|
* @param {Array} arr Form element array
|
|
*
|
|
* @return {Array}
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
getUniqueFormElements (arr)
|
|
{
|
|
let seen = {};
|
|
|
|
return arr.filter(function(item) {
|
|
return seen.hasOwnProperty(item.name) ? false : (seen[item.name] = true);
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Get form data
|
|
*
|
|
* @return {Object}
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
getData ()
|
|
{
|
|
const data = {},
|
|
elements = this.getFormElements(),
|
|
length = elements.length;
|
|
|
|
let value = null;
|
|
|
|
for (let i = 0; i < length; ++i) {
|
|
if (elements[i].tagName.toLowerCase() === 'canvas') {
|
|
value = elements[i].toDataURL('image/png');
|
|
} else {
|
|
value = elements[i].value;
|
|
}
|
|
|
|
data[jsOMS.Views.FormView.getElementId(elements[i])] = value;
|
|
}
|
|
|
|
return data;
|
|
};
|
|
|
|
/**
|
|
* Get form id
|
|
*
|
|
* @return {string}
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
getId ()
|
|
{
|
|
return this.id;
|
|
};
|
|
|
|
/**
|
|
* Validate form
|
|
*
|
|
* @return {boolean}
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
isValid ()
|
|
{
|
|
const elements = this.getFormElements(),
|
|
length = elements.length;
|
|
|
|
try {
|
|
for (let i = 0; i < length; ++i) {
|
|
if ((elements[i].required && elements[i].value === '')
|
|
|| (typeof elements[i].pattern !== 'undefined'
|
|
&& elements[i].pattern !== ''
|
|
&& !(new RegExp(elements[i].pattern)).test(elements[i].value))
|
|
) {
|
|
return false;
|
|
}
|
|
}
|
|
} catch (e) {
|
|
jsOMS.Log.Logger.instance.error(e);
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
/**
|
|
* Get form element
|
|
*
|
|
* @return {Object}
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
getElement ()
|
|
{
|
|
return document.getElementById(this.getId());
|
|
};
|
|
|
|
/**
|
|
* Get form element id
|
|
*
|
|
* @return {string}
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
static getElementId (e)
|
|
{
|
|
let id = e.getAttribute('name');
|
|
|
|
if (!id) {
|
|
id = e.getAttribute('id');
|
|
} else {
|
|
return id;
|
|
}
|
|
|
|
if (!id) {
|
|
id = e.getAttribute('type');
|
|
} else {
|
|
return id;
|
|
}
|
|
|
|
return id;
|
|
};
|
|
|
|
/**
|
|
* Get submit injects
|
|
*
|
|
* @return {Object}
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
getSubmitInjects ()
|
|
{
|
|
return this.submitInjects;
|
|
};
|
|
|
|
/**
|
|
* Bind form
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
bind ()
|
|
{
|
|
this.clean();
|
|
|
|
const e = document.getElementById(this.id);
|
|
|
|
if (!e) {
|
|
return;
|
|
}
|
|
|
|
this.method = typeof e.attributes['method'] !== 'undefined' ? e.attributes['method'].value : 'EMPTY';
|
|
this.action = typeof e.action !== 'undefined' ? e.action : 'EMPTY';
|
|
|
|
const elements = this.getFormElements(),
|
|
length = elements.length;
|
|
|
|
for (let i = 0; i < length; ++i) {
|
|
switch (elements[i].tagName) {
|
|
case 'input':
|
|
jsOMS.UI.Input.bind(elements[i]);
|
|
break;
|
|
case 'select':
|
|
this.bindSelect(elements[i]);
|
|
break;
|
|
case 'textarea':
|
|
this.bindTextarea(elements[i]);
|
|
break;
|
|
case 'button':
|
|
this.bindButton(elements[i]);
|
|
break;
|
|
default:
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Unbind form
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
unbind ()
|
|
{
|
|
const elements = this.getFormElements(),
|
|
length = elements.length;
|
|
|
|
for (let i = 0; i < length; ++i) {
|
|
switch (elements[i].tagName) {
|
|
case 'input':
|
|
jsOMS.UI.Input.unbind(elements[i]);
|
|
break;
|
|
case 'select':
|
|
this.bindSelect(elements[i]);
|
|
break;
|
|
case 'textarea':
|
|
this.bindTextarea(elements[i]);
|
|
break;
|
|
case 'button':
|
|
this.bindButton(elements[i]);
|
|
break;
|
|
default:
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Clean form
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
clean ()
|
|
{
|
|
this.unbind();
|
|
this.initializeMembers();
|
|
};
|
|
}
|
|
}(window.jsOMS = window.jsOMS || {}));
|