196 lines
6.4 KiB
JavaScript
196 lines
6.4 KiB
JavaScript
"use strict";
|
|
|
|
import {Check} from "../Utils/Check.ecma.js";
|
|
import {Utils} from "../Utils/Utils.ecma.js";
|
|
import {Attributes} from "../Application/Attributes.ecma.js";
|
|
|
|
/**
|
|
* @typedef {import("../Application/AnP.ecma.js").AnP} AnP
|
|
*/
|
|
|
|
/**
|
|
* @class
|
|
* @constructor
|
|
* @param {!AnP} anp
|
|
* @returns {void}
|
|
* @access public
|
|
*/
|
|
export const FormsComponent = (function(){
|
|
|
|
/**
|
|
* @constructs BaseComponent
|
|
* @param {!AnP} anp
|
|
* @returns {void}
|
|
* @access private
|
|
*/
|
|
const FormsComponent = function(anp){
|
|
|
|
/** @type {FormsComponent} */
|
|
const self = this;
|
|
/** @type {boolean} */
|
|
let started = false;
|
|
|
|
/**
|
|
* @returns {void}
|
|
* @access private
|
|
*/
|
|
const constructor = () => {};
|
|
|
|
/**
|
|
* @param {?anp_start_callback} callback
|
|
* @returns {boolean}
|
|
* @access public
|
|
*/
|
|
this.start = (callback = null) => {
|
|
|
|
/** @type {!anp_start_callback} */
|
|
const end = ok => {
|
|
Utils.execute(callback, ok);
|
|
return ok;
|
|
};
|
|
|
|
if(started)
|
|
return end(false);
|
|
return end(started = true);
|
|
};
|
|
|
|
/**
|
|
* @param {!(Object.<string, any|null>|Array.<any|null>)} inputs
|
|
* @returns {string}
|
|
* @access public
|
|
*/
|
|
this.build = inputs => {
|
|
|
|
/** @type {string|null} */
|
|
const i18n = Utils.get_value("i18n", inputs),
|
|
/** @type {string|null} */
|
|
text = Utils.get_value("text", inputs, Check.is_array(i18n) ? i18n[0] : i18n);
|
|
|
|
return ["form", {
|
|
class : "form",
|
|
on_submit : (item, event) => false,
|
|
method : "get",
|
|
action : "#"
|
|
}, [
|
|
["fieldset", null, [
|
|
anp.comp.i18n_text("legend", i18n, text),
|
|
anp.comp.i18n_text("p", Attributes.i18n_add_suffix(i18n, "text"), Utils.get_value("description", inputs, text)),
|
|
["div", {class : "structure"}, Utils.get_array(Utils.get_value("structure", inputs, [])).reduce((structure, item, i) => {
|
|
|
|
/** @type {[string|null, boolean]} */
|
|
const [type, is_array] = (
|
|
Check.is_array(item) ? [Check.is_string(item[0]) ? item[0] : null, true] :
|
|
Check.is_dictionary(item) ? [Check.is_string(item.type) ? item.type : null, false] :
|
|
[null, false]),
|
|
/** @type {string|null} */
|
|
name = Utils.get_value(["name", "i18n"], item),
|
|
/** @type {string|null} */
|
|
i18n = Utils.get_value(["i18n", "name"], item),
|
|
/** @type {string} */
|
|
id = Utils.get_value("id", item) || anp.random_chain(),
|
|
/** @type {string|null} */
|
|
text = Utils.get_value("text", item);
|
|
|
|
structure.push(["div", {
|
|
data_field : Utils.get_value("name", item, id),
|
|
data_i : i
|
|
}, [
|
|
["label", {for : id}, [
|
|
anp.comp.i18n(i18n, "span", text),
|
|
anp.comp.i18n_text("span",
|
|
Attributes.i18n_add_suffix(i18n, "description"),
|
|
Utils.get_value("description", item, text)
|
|
)
|
|
]],
|
|
["span", {class : "input"}, anp.comp[type] ? [anp.comp[type]([item, {id : id}])] : null],
|
|
["ul", {class : "errors"}]
|
|
]]);
|
|
|
|
return structure;
|
|
}, [])],
|
|
["ul", {class : "errors"}],
|
|
anp.comp.buttons(Utils.get_array(Utils.get_value(["buttons", "actions"], inputs, [])))
|
|
]]
|
|
]];
|
|
};
|
|
|
|
/**
|
|
* @param {!(HTMLFormElement|HTMLElement)} form
|
|
* @returns {Object.<string, any|null>}
|
|
* @access public
|
|
*/
|
|
this.get_data = form => {
|
|
|
|
/** @type {Object.<string, any|null>} */
|
|
const data = {};
|
|
|
|
(form = FormsComponent.get(form)) &&
|
|
form.querySelectorAll("[name]").forEach(item => {
|
|
|
|
/** @type {string} */
|
|
const name_attribute = item.getAttribute("name"),
|
|
/** @type {boolean} */
|
|
is_array = name_attribute.slice(-2) == "[]",
|
|
/** @type {string} */
|
|
name = is_array ? name_attribute.slice(0, -2) : name_attribute;
|
|
|
|
if(is_array)
|
|
(data[name] || (data[name] = [])).push(self.get_value(item));
|
|
else
|
|
data[name] = self.get_value(item);
|
|
|
|
});
|
|
|
|
return data;
|
|
};
|
|
|
|
/**
|
|
* @param {!HTMLElement} item
|
|
* @returns {any|null}
|
|
* @access public
|
|
*/
|
|
this.get_value = (item) => {
|
|
|
|
/** @type {string} */
|
|
const type = item.getAttribute("type"),
|
|
/** @type {string} */
|
|
tag = item.tagName.toLowerCase();
|
|
|
|
return (
|
|
type == "number" ? Number(item.value) :
|
|
type == "date" ? new Date(item.value) :
|
|
["radio", "checkbox"].includes(type) ? item.checked :
|
|
item.value);
|
|
};
|
|
|
|
constructor();
|
|
|
|
};
|
|
|
|
/**
|
|
* @param {!HTMLElement} form
|
|
* @returns {HTMLFormElement|null}
|
|
* @access public
|
|
* @static
|
|
*/
|
|
FormsComponent.get = form => {
|
|
|
|
if(form){
|
|
|
|
/** @type {HTMLFormElement} */
|
|
const child = form.querySelector && form.querySelector("form.form");
|
|
|
|
if(child)
|
|
form = child;
|
|
else
|
|
while((
|
|
(form.tagName && form.tagName.toLowerCase() != "form") ||
|
|
(form.classList && !form.classList.contains("form"))
|
|
) && (form = form.parentNode));
|
|
};
|
|
|
|
return form || null;
|
|
};
|
|
|
|
return FormsComponent;
|
|
})(); |