152 lines
5.0 KiB
JavaScript
152 lines
5.0 KiB
JavaScript
"use strict";
|
|
|
|
import {Fieldset, Div, Form, UL} from "../Utils/HTMLDSL.ecma.js";
|
|
|
|
/**
|
|
* @class FormsComponent
|
|
* @constructor
|
|
* @param {!AnP} anp
|
|
* @return {void}
|
|
* @access private
|
|
* @static
|
|
*/
|
|
export const FormsComponent = (function(){
|
|
|
|
/**
|
|
* @callback form_submit_callback
|
|
* @param {!HTMLElement} form
|
|
* @param {!Event} event
|
|
* @return {any|null|void}
|
|
*/
|
|
|
|
/**
|
|
* @constructs FormsComponent
|
|
* @param {!AnP} anp
|
|
* @return {void}
|
|
* @access private
|
|
* @static
|
|
*/
|
|
const FormsComponent = function(anp){
|
|
|
|
/** @type {FormsComponent} */
|
|
const self = this;
|
|
|
|
/**
|
|
* @returns {void}
|
|
* @access private
|
|
*/
|
|
const constructor = () => {
|
|
|
|
setTimeout(() => {
|
|
anp.components.forms = self;
|
|
anp.components.form = self.build;
|
|
}, 0);
|
|
|
|
};
|
|
|
|
/**
|
|
* @param {string} name
|
|
* @param {!(Object.<string, any|null>|Array.<any|null>)} inputs
|
|
* @return {Array.<any|null>}
|
|
* @access public
|
|
*/
|
|
this.build = (name, inputs) => {
|
|
|
|
/** @type {form_submit_callback|null} */
|
|
const submit = Common.get_value("submit", inputs, null);
|
|
|
|
return Form({
|
|
data_name : name,
|
|
method : Common.get_value("method", inputs, "post"),
|
|
action : Common.get_value("action", inputs, "#"),
|
|
...(submit ? {on_submit : submit} : {})
|
|
}, [
|
|
Fieldset({class : "form"}, [
|
|
anp.components.i18n(name, "legend"),
|
|
anp.components.i18n(name + "_description", "p"),
|
|
Div({class : "form-fields"}, Common.get_value("structure", inputs, []).map(([type, name, ...inputs], i) => {
|
|
|
|
/** @type {string} */
|
|
let id = anp.unique_keys.create(true),
|
|
/** @type {number} */
|
|
l = inputs.length - 1;
|
|
|
|
if(!Check.is_dictionary(inputs[l])){
|
|
inputs.push({});
|
|
l ++;
|
|
};
|
|
inputs[l].id = id;
|
|
|
|
return Div({
|
|
data_field : name,
|
|
data_i : i
|
|
}, [
|
|
Label({
|
|
for : id,
|
|
data_i18n : name,
|
|
data_i18n_without : true,
|
|
title : anp.components.i18n(name, "label")
|
|
}, [
|
|
anp.components.i18n(name),
|
|
anp.components.i18n(name + "_description"),
|
|
]),
|
|
Span({class : "value"}, [
|
|
anp.components[type](name, ...inputs)
|
|
]),
|
|
UL({class : "errors"})
|
|
]);
|
|
})),
|
|
UL({class : "global-errors"}),
|
|
Div({class : "buttons"}, Common.get_value(["actions", "buttons"], inputs, []).concat(
|
|
anp.components.button(Common.get_value("submit_reset", inputs, "reset"), "reset"),
|
|
submit ? anp.components.button(Common.get_value("submit_name", inputs, "submit"), "submit") : null
|
|
))
|
|
])
|
|
]);
|
|
};
|
|
|
|
this.get = item => {
|
|
|
|
if(item)
|
|
while(item.tagName.toLowerCase() != "form" && (item = item.parentElement));
|
|
|
|
return item;
|
|
};
|
|
|
|
this.get_values = form => [...self.get(form).querySelectorAll("[name]")].reduce((values, field) => {
|
|
|
|
let name = field.getAttribute("name");
|
|
const is_array = self.is_array(field),
|
|
tag = field.tagName.toLowerCase(),
|
|
type = field.getAttribute("type").toLowerCase().trim();
|
|
|
|
if(is_array){
|
|
(values[name = name.slice(0, -2)] = values[name] || []).push(self.get_value(field));
|
|
}else
|
|
values[name] = self.get_value(field);
|
|
|
|
return values;
|
|
}, {});
|
|
|
|
this.is_array = input => input.getAttribute("name").endsWith("[]");
|
|
|
|
this.get_value = input => {
|
|
switch(input.tagName.toLowerCase()){
|
|
case "select":
|
|
return input.multiple ? [...input.options].filter(option => option.selected).map(option => option.value) : input.value;
|
|
};
|
|
switch(input.getAttribute("type")){
|
|
case "checkbox":
|
|
case "radio":
|
|
return self.is_array(input) ? input.checked ? input.value : null : input.checked;
|
|
case "number":
|
|
return parseFloat(input.value) || 0;
|
|
};
|
|
return input.value;
|
|
};
|
|
|
|
constructor();
|
|
};
|
|
|
|
return FormsComponent;
|
|
})(); |