Signed-off-by: Avior <florian.bouillon@delta-wings.net>
This commit is contained in:
Florian Bouillon 2019-12-06 15:32:35 +01:00
parent 925b9c2d7f
commit dbe53cb3f9
No known key found for this signature in database
GPG Key ID: B143FF27EF555D16
19 changed files with 131 additions and 65 deletions

View File

@ -1,6 +1,6 @@
import FormManager from "./FormManager"; import FormManager from "./FormManager";
import InputAbstract from "./modules/InputAbstract"; import InputAbstract from "./modules/AbstractInput";
import AttributeAbstract from "./attributes/AttributeAbstract"; import AbstractAttribute from "./attributes/AbstractAttribute";
import AttributeIdentity from "./attributes/Interfaces/AttributeIdentity"; import AttributeIdentity from "./attributes/Interfaces/AttributeIdentity";
import AttributeListeners from "./attributes/AttributeListeners"; import AttributeListeners from "./attributes/AttributeListeners";
@ -16,17 +16,16 @@ export default class AttributesManager {
this.form = form this.form = form
} }
public register(...attribute: typeof AttributeAbstract[]) { public register(...attribute: typeof AbstractAttribute[]) {
for (const attr of attribute) { for (const attr of attribute) {
this.attributesArray.push(attr.identity) this.attributesArray.push(attr.identity)
} }
} }
public trigger(event: AttributeListeners, data?: any): boolean|object { public trigger(event: AttributeListeners, data?: any): boolean {
if (!this.eventsListenersItems[event]) return true if (!this.eventsListenersItems[event]) return true
for (const el of this.eventsListenersItems[event]) { for (const el of this.eventsListenersItems[event]) {
const res = el.trigger(event, data) el.trigger(event, data)
if (typeof res !== "undefined") return res
} }
return true return true
} }
@ -83,5 +82,5 @@ export default class AttributesManager {
} }
interface listenerItems { interface listenerItems {
[key:string]: AttributeAbstract[] [key:string]: AbstractAttribute[]
} }

View File

@ -7,7 +7,8 @@ import RegexAttribute from './attributes/RegexAttribute'
import IgnoreAttribute from './attributes/IgnoreAttribute' import IgnoreAttribute from './attributes/IgnoreAttribute'
import DefaultAttribute from './attributes/DefaultAttribute' import DefaultAttribute from './attributes/DefaultAttribute'
import AutosetAttribute from './attributes/AutosetAttribute' import AutosetAttribute from './attributes/AutosetAttribute'
import checkboxInput from './modules/CheckboxInput' import CheckboxInput from './modules/CheckboxInput'
import NumberInput from './modules/NumberInput'
/** /**
* This class is Mainly used for (non-npm) browser usage as it contains every buitins extensions * This class is Mainly used for (non-npm) browser usage as it contains every buitins extensions
@ -24,7 +25,8 @@ export default class fm extends FormManager {
DateInput, DateInput,
RepeatInput, RepeatInput,
SelectInput, SelectInput,
checkboxInput, CheckboxInput,
NumberInput,
) )
this.setupInputs() this.setupInputs()
this.attributeManager.register( this.attributeManager.register(

View File

@ -1,7 +1,7 @@
import AttributesManager from './AttributesManager'; import AttributesManager from './AttributesManager';
import InputIdentity from './modules/Interfaces/InputIdentity'; import InputIdentity from './modules/Interfaces/InputIdentity';
import DefaultInput from './modules/DefaultInput'; import DefaultInput from './modules/DefaultInput';
import InputAbstract from './modules/InputAbstract'; import AbstractInput from './modules/AbstractInput';
import InputArray from "./modules/Interfaces/InputArray"; import InputArray from "./modules/Interfaces/InputArray";
import AttributeListeners from './attributes/AttributeListeners'; import AttributeListeners from './attributes/AttributeListeners';
@ -84,10 +84,11 @@ export default class FormManager {
/** /**
* Add to the Manager an Input * Add to the Manager an Input
* *
* @param {InputIdentity[]} inter the interface used * @param {...(typeof AbstractInput[])} inter the interface used
* @memberof FormManager * @memberof FormManager
*/ */
public assign(...inter: (typeof InputAbstract[])) {
public assign(...inter: (typeof AbstractInput[])) {
for (const input of inter) { for (const input of inter) {
this.FMInputs.unshift(input.identity) this.FMInputs.unshift(input.identity)
} }
@ -120,7 +121,7 @@ export default class FormManager {
* @returns {FMInput} * @returns {FMInput}
* @memberof FormManager * @memberof FormManager
*/ */
public getInit(element: HTMLElement): InputAbstract|void { public getInit(element: HTMLElement): AbstractInput|void {
inputsLoop: for (const input of this.FMInputs) { inputsLoop: for (const input of this.FMInputs) {
if (input.classes != undefined) { if (input.classes != undefined) {
let tmpList: string[] = [] let tmpList: string[] = []
@ -152,11 +153,11 @@ export default class FormManager {
* Verify the inputs for errors * Verify the inputs for errors
* *
* @param {boolean} [quick=false] define if the loop should stop after the first error * @param {boolean} [quick=false] define if the loop should stop after the first error
* @returns {InputAbstract[]} return an array containing the errored elements (Empty if not error) * @returns {AbstractInput[]} return an array containing the errored elements (Empty if not error)
* @memberof FormManager * @memberof FormManager
*/ */
public validate(quick = false): InputAbstract[] { public validate(quick = false): AbstractInput[] {
const errored: InputAbstract[] = [] const errored: AbstractInput[] = []
for (const name in this.inputs) { for (const name in this.inputs) {
if (!this.inputs.hasOwnProperty(name)) continue if (!this.inputs.hasOwnProperty(name)) continue
const input = this.inputs[name]; const input = this.inputs[name];
@ -208,6 +209,20 @@ export default class FormManager {
return true return true
} }
/**
* Manually set the value of an element
*
* @param {string} name
* @param {*} value
* @memberof FormManager
*/
public setValue(name: string, value: any) {
if (!this.inputs.hasOwnProperty(name)) {
return
}
const input = this.inputs[name]
input.setValue(value)
}
/** /**
* Return the JSON `{key: value}` sequence * Return the JSON `{key: value}` sequence
* *

View File

@ -21,11 +21,11 @@ export function evalF(str: string, callback?: (str: string) => void): boolean {
* *
* @param str the string to transform * @param str the string to transform
*/ */
export function toNumber(str: any): number|undefined { export function toNumber(str: any): number | undefined {
if (typeof str === "number") return str if (typeof str === "number") return str
if ((str === "" || str === undefined || typeof(str) === "boolean")) return undefined if (str === "" || typeof str !== "string") return undefined
// return undefined if it must be shown as string
// console.log("toNumber", str) // str is a string
if ((str.startsWith("0") || str.startsWith("+")) && str.length > 1) return undefined if ((str.startsWith("0") || str.startsWith("+")) && str.length > 1) return undefined
const n = Number(str) const n = Number(str)
if (!isNaN(n)) { if (!isNaN(n)) {
@ -35,30 +35,33 @@ export function toNumber(str: any): number|undefined {
} }
export function isNumber(el: any): boolean { export function isNumber(el: any): boolean {
// console.log(el) return typeof toNumber(el) === "number"
return typeof el === "number"
} }
export function toBoolean(str: any): boolean|undefined { export function toBoolean(str: any): boolean | undefined {
if (typeof str === "boolean") return str if (typeof str === "boolean") return str
if (str === "true") return true if (str === "true") return true
if (str === "false") return false if (str === "false") return false
return undefined return undefined
} }
export function strToNum(str: string): number|string { export function isBoolean(el: any): boolean {
return typeof toBoolean(el) === "boolean"
}
export function strToNum(str: string): number | string {
const n = toNumber(str) const n = toNumber(str)
if (n) return n if (n) return n
return str return str
} }
export function realType(el: any): string|number|boolean|undefined {
export function realType(el: any): string|number|boolean { // If el is `null` or `undefined`
if ((typeof el === "object" && el === null) || typeof el === "undefined") return undefined
if (typeof el === "object" && el.hasOwnProperty("id")) { if (typeof el === "object" && el.hasOwnProperty("id")) {
el = el.id el = el.id
} }
if (isNumber(el)) return el if (isNumber(el)) return toNumber(el)
const isBool = toBoolean(el) if (isBoolean(el)) return toBoolean(el)
const isNum = toNumber(el) return el
return typeof isBool === "boolean" ? isBool : typeof isNum === "number" ? isNum : el
} }

View File

@ -1,8 +1,8 @@
import AttributeIdentity from './Interfaces/AttributeIdentity'; import AttributeIdentity from './Interfaces/AttributeIdentity';
import InputAbstract from "../modules/InputAbstract"; import InputAbstract from "../modules/AbstractInput";
import AttributeListeners from "./AttributeListeners"; import AttributeListeners from "./AttributeListeners";
export default abstract class AttributeAbstract { export default abstract class AbstractAttribute {
public input: InputAbstract public input: InputAbstract

View File

@ -1,6 +1,6 @@
import { evalF } from "../Functions"; import { evalF } from "../Functions";
import AttributeListeners from "./AttributeListeners"; import AttributeListeners from "./AttributeListeners";
import AttributeAbstract from "./AttributeAbstract"; import AbstractAttribute from "./AbstractAttribute";
import AttributeIdentity from "./Interfaces/AttributeIdentity"; import AttributeIdentity from "./Interfaces/AttributeIdentity";
/** /**
@ -24,7 +24,7 @@ import AttributeIdentity from "./Interfaces/AttributeIdentity";
* @implements {FMAFormInitInterface} * @implements {FMAFormInitInterface}
*/ */
export default class AutosetAttribute export default class AutosetAttribute
extends AttributeAbstract { extends AbstractAttribute {
public trigger(): boolean | void | object { public trigger(): boolean | void | object {
let str = this.input.element.getAttribute("data-autoset") || "" let str = this.input.element.getAttribute("data-autoset") || ""

View File

@ -1,5 +1,5 @@
import { evalF } from "../Functions"; import { evalF } from "../Functions";
import AttributeAbstract from "./AttributeAbstract"; import AbstractAttribute from "./AbstractAttribute";
import AttributeListeners from "./AttributeListeners"; import AttributeListeners from "./AttributeListeners";
import AttributeIdentity from "./Interfaces/AttributeIdentity"; import AttributeIdentity from "./Interfaces/AttributeIdentity";
@ -24,13 +24,18 @@ import AttributeIdentity from "./Interfaces/AttributeIdentity";
* @implements {FMAFormInitInterface} * @implements {FMAFormInitInterface}
*/ */
export default class DefaultAttribute export default class DefaultAttribute
extends AttributeAbstract { extends AbstractAttribute {
public trigger(): boolean | void | object { public trigger(): boolean | void | object {
this.run() this.run()
return true return true
} }
private run() { private run() {
// Dont override existing value
if (this.input.getValue() !== undefined) {
return
}
let attrVal = this.input.element.getAttribute("data-default") let attrVal = this.input.element.getAttribute("data-default")
// if element has a date,time,week type // if element has a date,time,week type
@ -66,7 +71,8 @@ extends AttributeAbstract {
// if default is an attribute value // if default is an attribute value
if (!el.hasAttribute(splitted[1])) throw Error(`Error: "${this.input.getName()}" element don't have the attribute "${splitted[1]}"`) if (!el.hasAttribute(splitted[1])) throw Error(`Error: "${this.input.getName()}" element don't have the attribute "${splitted[1]}"`)
return this.input.setValue(el.getAttribute(splitted[1])) this.input.setValue(el.getAttribute(splitted[1]))
return
} }
this.input.setValue(attrVal) this.input.setValue(attrVal)
} }

View File

@ -1,4 +1,4 @@
import AttributeAbstract from "./AttributeAbstract"; import AbstractAttribute from "./AbstractAttribute";
import AttributeListeners from "./AttributeListeners"; import AttributeListeners from "./AttributeListeners";
import AttributeIdentity from "./Interfaces/AttributeIdentity"; import AttributeIdentity from "./Interfaces/AttributeIdentity";
@ -23,7 +23,7 @@ import AttributeIdentity from "./Interfaces/AttributeIdentity";
* @implements {FMAFormInitInterface} * @implements {FMAFormInitInterface}
*/ */
export default class IgnoreAttribute export default class IgnoreAttribute
extends AttributeAbstract { extends AbstractAttribute {
public trigger(_: AttributeListeners, data?: any): boolean | void | object { public trigger(_: AttributeListeners, data?: any): boolean | void | object {
data[this.input.getName()] = undefined data[this.input.getName()] = undefined
return data return data

View File

@ -1,5 +1,5 @@
import InputAbstract from "../../modules/InputAbstract"; import InputAbstract from "../../modules/AbstractInput";
import AttributeAbstract from "../AttributeAbstract"; import AbstractAttribute from "../AbstractAttribute";
import AttributeListeners from "../AttributeListeners"; import AttributeListeners from "../AttributeListeners";
import AttributeIdentity from "./AttributeIdentity"; import AttributeIdentity from "./AttributeIdentity";
@ -7,7 +7,7 @@ import AttributeIdentity from "./AttributeIdentity";
* Define static elements of `AttributeAbstract` * Define static elements of `AttributeAbstract`
*/ */
export default interface AttributeInterface { export default interface AttributeInterface {
new(input: InputAbstract): AttributeAbstract new(input: InputAbstract): AbstractAttribute
listeners: AttributeListeners[] listeners: AttributeListeners[]
identity: AttributeIdentity identity: AttributeIdentity
} }

View File

@ -1,9 +1,9 @@
import AttributeIdentity from './Interfaces/AttributeIdentity'; import AttributeIdentity from './Interfaces/AttributeIdentity';
import AttributeAbstract from './AttributeAbstract'; import AbstractAttribute from './AbstractAttribute';
import AttributeListeners from "./AttributeListeners"; import AttributeListeners from "./AttributeListeners";
export default class RegexAttribute export default class RegexAttribute
extends AttributeAbstract { extends AbstractAttribute {
public trigger(): boolean { public trigger(): boolean {
const regStr = this.input.element.dataset.regex const regStr = this.input.element.dataset.regex
if (!regStr) return true if (!regStr) return true

View File

@ -12,9 +12,11 @@ export default class CheckboxInput extends DefaultInput {
public setValue(value: any) { public setValue(value: any) {
this.element.checked = this.formatValue(value) this.element.checked = this.formatValue(value)
} }
public getValue(): boolean { public getValue(): boolean {
return this.element.checked return this.element.checked
} }
public formatValue(value: any): boolean { public formatValue(value: any): boolean {
value = toBoolean(value) value = toBoolean(value)
if (typeof value === "undefined") { if (typeof value === "undefined") {

View File

@ -9,7 +9,6 @@ import DefaultInput from './DefaultInput'
export default class DateInput extends DefaultInput { export default class DateInput extends DefaultInput {
public setValue(value: any) { public setValue(value: any) {
// handle GO null value
const format = this.formatValue(value) const format = this.formatValue(value)
if (typeof format === "object") { if (typeof format === "object") {
this.element.valueAsDate = format this.element.valueAsDate = format
@ -28,6 +27,7 @@ export default class DateInput extends DefaultInput {
if (typeof val === "object" && typeof val.getDate === "function") { if (typeof val === "object" && typeof val.getDate === "function") {
return (val as Date) return (val as Date)
} }
// handle GO null value
if (val === "0001-01-01T00:00:00Z") { if (val === "0001-01-01T00:00:00Z") {
return undefined return undefined
} }

View File

@ -1,11 +1,11 @@
import { realType } from "../Functions" import { realType } from "../Functions"
import InputAbstract from "./InputAbstract" import AbstractInput from "./AbstractInput"
import InputIdentity from "./Interfaces/InputIdentity" import InputIdentity from "./Interfaces/InputIdentity"
export default class DefaultInput extends InputAbstract { export default class DefaultInput extends AbstractInput {
public setValue(value: any) { public setValue(value: any) {
this.element.value = this.formatValue(value) this.element.value = this.formatValue(value) || ""
} }
public getValue(): any { public getValue(): any {
@ -13,7 +13,6 @@ export default class DefaultInput extends InputAbstract {
} }
public formatValue(value: any): any { public formatValue(value: any): any {
if (typeof value === "undefined") return ""
// if the value is a number return it as a number obj // if the value is a number return it as a number obj
return realType(value) return realType(value)
} }

View File

@ -1,4 +1,4 @@
import InputAbstract from "../InputAbstract"; import AbstractInput from "../AbstractInput";
/** /**
* this interface is used for fetching and setting `name` to `FMInput` link * this interface is used for fetching and setting `name` to `FMInput` link
@ -6,5 +6,5 @@ import InputAbstract from "../InputAbstract";
* @interface InputArray * @interface InputArray
*/ */
export default interface InputArray { export default interface InputArray {
[key: string]: InputAbstract [key: string]: AbstractInput
} }

View File

@ -1,8 +1,8 @@
import InputAbstract from "../InputAbstract"; import AbstractInput from "../AbstractInput";
import FormManager from "../../FormManager"; import FormManager from "../../FormManager";
interface InputConstructor { interface InputConstructor {
new(element: HTMLElement, form: FormManager): InputAbstract new(element: HTMLElement, form: FormManager): AbstractInput
} }
/** /**

View File

@ -0,0 +1,25 @@
import InputIdentity from './Interfaces/InputIdentity';
import DefaultInput from './DefaultInput';
import { toNumber, isNumber } from '../Functions';
/**
*
* @class FMDateInput
* @extends {FMInput}
*/
export default class NumberInput extends DefaultInput {
public formatValue(value: any): number|undefined {
const n = toNumber(value)
return n
}
public verify(): boolean {
return typeof this.getValue() === "undefined" || isNumber(this.getValue())
}
public static identity: InputIdentity = {
input: NumberInput,
type: "number"
}
}

View File

@ -1,6 +1,6 @@
import FormManager from "../FormManager" import FormManager from "../FormManager"
import DefaultInput from './DefaultInput'; import DefaultInput from './DefaultInput';
import InputAbstract from './InputAbstract'; import InputAbstract from './AbstractInput';
import InputIdentity from './Interfaces/InputIdentity'; import InputIdentity from './Interfaces/InputIdentity';
/** /**
@ -89,14 +89,15 @@ export default class RepeatInput extends DefaultInput {
input.element.disabled = true input.element.disabled = true
} }
sub.push(input) sub.push(input)
// if values is a named array // if values is a named array
if (values != undefined && values[input.getName()] != undefined) { if (values != undefined && values[input.getName()] != undefined) {
input.setValue(values[input.getName()]) input.setValue(values[input.getName()])
return
} }
// if value is a single string/number/etc
if (typeof(values) != "object" && values != undefined) { // Set default value
input.setValue(values) input.setValue(values)
}
}) })
this.elements.push(sub) this.elements.push(sub)

View File

@ -9,14 +9,28 @@ import { realType } from '../Functions';
*/ */
export default class SelectInput extends DefaultInput { export default class SelectInput extends DefaultInput {
public formatValue(value: any): any { public setValue(value: any) {
if (typeof value === "undefined") { value = realType(value)
const opt: HTMLOptionElement|null = this.element.querySelector("option[selected]") let opt:HTMLOptionElement|undefined = this.element.querySelector(`option[value="${value}"]`) || undefined
if (opt) { if (opt) {
return opt.value this.element.value = value
} return
} }
return realType(value) opt = this.element.querySelector("option[selected]") || undefined
if (opt) {
this.element.value = opt.value
}
}
public formatValue(value: any): any {
if (typeof value !== "undefined" && value !== "") {
return realType(value)
}
const opt: HTMLOptionElement|undefined = this.element.querySelector("option[selected]") || undefined
if (opt) {
return opt.value
}
throw Error(":O it should never come here")
} }
public static identity: InputIdentity = { public static identity: InputIdentity = {