Moved objects

This commit is contained in:
Florian Bouillon 2019-11-14 12:15:48 +01:00
parent 135f6aa770
commit dc40b373ff
No known key found for this signature in database
GPG Key ID: B143FF27EF555D16
25 changed files with 408 additions and 302 deletions

View File

@ -1,4 +1,5 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

View File

@ -1,6 +1,9 @@
import FormManager from "./FormManager";
import FMAttribute, { FMAttributeAssignment, FMAttributeListeners, TriggerCallback } from "./FMAttribute";
import FMInput from "./FMInput";
import InputAbstract from "./modules/InputAbstract";
import AttributeAbstract from "./attributes/AttributeAbstract";
import AttributeIdentity from "./attributes/Interfaces/AttributeIdentity";
import AttributeListeners from "./attributes/AttributeListeners";
export default class AttributesManager {
@ -8,7 +11,7 @@ export default class AttributesManager {
private form: FormManager
private attributesArray: FMAttributeAssignment[] = []
private attributesArray: AttributeIdentity[] = []
private eventsListenersItems: listenerItems = {}
@ -17,15 +20,13 @@ export default class AttributesManager {
AttributesManager.instance = this
}
public register(...attribute: FMAttributeAssignment[]) {
this.attributesArray.push(...attribute)
public register(...attribute: typeof AttributeAbstract[]) {
for (const attr of attribute) {
this.attributesArray.push(attr.identity)
}
}
public registerSingle(attribute: FMAttributeAssignment) {
this.attributesArray.push(attribute)
}
public trigger(event: FMAttributeListeners, data?: any): boolean|TriggerCallback {
public trigger(event: AttributeListeners, data?: any): boolean|object {
if (!this.eventsListenersItems[event]) return true
for (const el of this.eventsListenersItems[event]) {
const res = el.trigger(event, data)
@ -34,7 +35,7 @@ export default class AttributesManager {
return true
}
public triggerElement(event: FMAttributeListeners, input: FMInput, data?: any): boolean|TriggerCallback {
public triggerElement(event: AttributeListeners, input: InputAbstract, data?: any): boolean|object {
if (!this.eventsListenersItems[event]) return true
for (const el of this.eventsListenersItems[event]) {
if (el.input === input) {
@ -47,7 +48,7 @@ export default class AttributesManager {
public onChange(this: HTMLInputElement) {
const self = AttributesManager.instance
console.log(self.trigger(FMAttributeListeners.CHANGE, self.form.inputs[this.name]))
self.trigger(AttributeListeners.CHANGE, self.form.inputs[this.name])
}
// private onChange
@ -84,5 +85,5 @@ export default class AttributesManager {
}
interface listenerItems {
[key:string]: FMAttribute[]
[key:string]: AttributeAbstract[]
}

View File

@ -1,82 +0,0 @@
import FormManager from "./FormManager"
import { realType } from "./Functions"
export default class FMInput {
element: HTMLInputElement
form: FormManager
required: boolean
constructor(element: Element, form: FormManager) {
this.element = element as HTMLInputElement
this.form = form
this.required = element.hasAttribute("required")
}
/**
* Set the element Value
*
* @param {*} value the input value
*
* _hint: pass it through this.formatValue_
*
* @memberof FMInput
*/
public setValue(value: any) {
this.element.value = value
}
/**
* Get the element value
*
* @returns {*} the value
* @memberof FMInput
*/
public getValue(): any {
return this.formatValue(this.element.value)
}
/**
* Format the value into a usable one by the module
*
* for elements like `select` if the value don't correspond to something
* it will return the default `value`
*
* @param {*} value
* @returns {*}
* @memberof FMInput
*/
public formatValue(value: any): any {
// if the value is a number return it as a number obj
return realType(value)
}
/**
* Retrieve the input name
*
* @returns {string}
* @memberof FMInput
*/
public getName(): string {
// while we search for inputs containing [name] we search for the input real name in [name] or [data-name]
// (Allow other inputs to play with inputs)
let attr = this.element.getAttribute("name") || this.element.dataset.name;
if (attr) return attr
throw Error("Error: could not get input name!")
}
/**
* Verify if the element is correct
*
* @returns {boolean}
* @memberof FMInput
*/
public verify(): boolean {
let val: any = this.getValue()
// if element is required and value is undefined retur false
if (this.required && (val === undefined || val === null || val === "")) return false
return true
}
}

View File

@ -1,7 +1,10 @@
import { InputArray, InputAssignment } from './Interfaces';
import FMInput from "./FMInput"
import AttributesManager from './AttributesManager';
import { FMAttributeListeners } from './FMAttribute';
import InputIdentity from './modules/Interfaces/InputIdentity';
import DefaultInput from './modules/DefaultInput';
import InputAbstract from './modules/InputAbstract';
import InputArray from "./modules/Interfaces/InputArray";
import AttributeListeners from './attributes/AttributeListeners';
/*!
* FormManager by DZEIO's team
@ -30,10 +33,10 @@ export default class FormManager {
* List of interfaces
*
* @private
* @type {InputAssignment[]}
* @type {InputIdentity[]}
* @memberof FormManager
*/
private FMInputs: InputAssignment[] = []
private FMInputs: InputIdentity[] = []
/**
* The last verified `FMInput` that returned an error
@ -41,7 +44,7 @@ export default class FormManager {
* @type {FMInput}
* @memberof FormManager
*/
public lastErroredInput: FMInput|undefined
public lastErroredInput: InputAbstract|undefined
/**
* The Form Element of the FM
@ -69,32 +72,22 @@ export default class FormManager {
}
//assign default form interface
this.assign({
input: FMInput
})
this.assign(DefaultInput)
//Setup the system for basic inputs
this.setupInputs()
}
/**
* Add the the FM an Input Manager
* Add to the Manager an Input
*
* @param {FMAssignInterface} inter the interface used
* @param {InputIdentity[]} inter the interface used
* @memberof FormManager
*/
public assign(...inter: InputAssignment[]) {
this.FMInputs.unshift(...inter)
}
/**
* Assign a single Module
*
* @param {FMAssignInterface} inter
* @memberof FormManager
*/
public assignSingle(inter: InputAssignment) {
this.FMInputs.unshift(inter)
public assign(...inter: (typeof InputAbstract[])) {
for (const input of inter) {
this.FMInputs.unshift(input.identity)
}
}
/**
@ -103,12 +96,12 @@ export default class FormManager {
* @memberof FormManager
*/
public setupInputs() {
this.inputs = {}
this.form.querySelectorAll("[name]:not([data-name])").forEach((element: Element) => {
this.inputs = {};
(this.form.querySelectorAll("[name]:not([data-name])") as NodeListOf<HTMLElement>).forEach((element: HTMLElement) => {
let el = this.getInit(element)
if (el) this.inputs[el.getName()] = el
});
this.attributeManager.trigger(FMAttributeListeners.FORM_INIT)
this.attributeManager.trigger(AttributeListeners.FORM_INIT)
}
/**
@ -118,7 +111,7 @@ export default class FormManager {
* @returns {FMInput}
* @memberof FormManager
*/
public getInit(element: Element): FMInput|void {
public getInit(element: HTMLElement): InputAbstract|void {
inputsLoop: for (const input of this.FMInputs) {
if (input.classes != undefined) {
let tmpList: string[] = []
@ -158,7 +151,7 @@ export default class FormManager {
for (const name in this.inputs) {
if (this.inputs.hasOwnProperty(name)) {
const input = this.inputs[name];
const res = this.attributeManager.triggerElement(FMAttributeListeners.VERIFY, input) as boolean
const res = this.attributeManager.triggerElement(AttributeListeners.VERIFY, input) as boolean
if(!input.verify() || !res) {
console.log(input.verify(), res)
this.lastErroredInput = input
@ -183,9 +176,9 @@ export default class FormManager {
public submit(url: string, callback?: (this: XMLHttpRequest, ev: ProgressEvent) => void, verify: boolean = true): boolean {
if (verify && !this.verify()) return false
let toSend = this.getJSON()
let event = this.attributeManager.trigger(FMAttributeListeners.FORM_SUBMIT, toSend)
if (typeof event !== "boolean" && event.datas && event.result) {
toSend = event.datas
let event = this.attributeManager.trigger(AttributeListeners.FORM_SUBMIT, toSend)
if (typeof event !== "boolean" && event) {
toSend = event
}
let ajax = new XMLHttpRequest
ajax.open("POST", url, true)
@ -227,7 +220,7 @@ export default class FormManager {
else console.warn(`${key} is not a valid input name`)
}
}
this.attributeManager.trigger(FMAttributeListeners.FORM_FILL)
this.attributeManager.trigger(AttributeListeners.FORM_FILL)
}
/**
@ -292,7 +285,7 @@ export default class FormManager {
* @memberof FormManager
*/
public clear() {
if (this.attributeManager.trigger(FMAttributeListeners.PRE_CLEAR) === false) return
if (this.attributeManager.trigger(AttributeListeners.PRE_CLEAR) === false) return
(this.form.querySelectorAll("[name]") as NodeListOf<HTMLInputElement>).forEach((el: HTMLInputElement) => {
for (const name in this.inputs) {
if (this.inputs.hasOwnProperty(name)) {
@ -301,7 +294,7 @@ export default class FormManager {
}
}
})
this.attributeManager.trigger(FMAttributeListeners.POST_CLEAR)
this.attributeManager.trigger(AttributeListeners.POST_CLEAR)
}
}

View File

@ -20,8 +20,8 @@ export function evalF(str: string, callback?: (str: string) => void): boolean {
*
* @param str the string to transform
*/
export function toNumber(str: string): number|undefined {
if (str === "") return undefined
export function toNumber(str: any): number|undefined {
if (str === "" || str === undefined) return undefined
// return undefined if it must be shown as string
if ((str.startsWith("0") || str.startsWith("+")) && str.length > 1) return undefined
const n = Number(str)
@ -31,7 +31,11 @@ export function toNumber(str: string): number|undefined {
return undefined
}
export function toBoolean(str: string): boolean|undefined {
export function isNumber(el: any): boolean {
return typeof el === "number"
}
export function toBoolean(str: any): boolean|undefined {
if (str === "true") return true
if (str === "false") return false
return undefined
@ -44,7 +48,8 @@ export function strToNum(str: string): number|string {
}
export function realType(el: string): string|number|boolean {
export function realType(el: any): string|number|boolean {
if (isNumber(el)) return el
const isBool = toBoolean(el)
const isNum = toNumber(el)
return typeof isBool === "boolean" ? isBool : typeof isNum === "number" ? isNum : el

View File

@ -1,31 +0,0 @@
import FMInput from "./FMInput"
/**
* this interface is used for fetching and setting `name` to `FMInput` link
*
* @interface InputArray
*/
export interface InputArray {
[key: string]: FMInput
}
/**
* this interface is used when adding a new `FMInput` class to the FormManager
*
* @interface FMAssignInterface
*/
export interface FMAssignInterface {
input: typeof FMInput
classes?: string[] | string
attributes?: string[] | string
type?: string
tagName?: string
}
export interface InputAssignment {
input: typeof FMInput
classes?: string[] | string
attributes?: string[] | string
type?: string
tagName?: string
}

View File

@ -0,0 +1,23 @@
import AttributeIdentity from './Interfaces/AttributeIdentity';
import InputAbstract from "../modules/InputAbstract";
import AttributeListeners from "./AttributeListeners";
export default abstract class AttributeAbstract {
public input: InputAbstract
public static listeners: AttributeListeners[]
public static identity: AttributeIdentity
public constructor(input: InputAbstract) {
this.input = input
}
/**
* Function launched on Listener trigger
* it MUST be implemented and SHOULD return boolean
*
* @param ev Attribue triggered
*/
public abstract trigger(event: AttributeListeners, data?: any): object|boolean|void
}

View File

@ -0,0 +1,11 @@
enum AttributeListeners {
PRE_CLEAR, // Event run before clearing the form
POST_CLEAR, // Event run after learing the form
CHANGE, // Event runs on Form Change (datas wil be filled with the FMInput element)
FORM_INIT, // Event runs on form init
FORM_SUBMIT, // Event run before submitting (datas is filled with the datas that will be submitted, MUST return TriggerCallback)
VERIFY, // Event run on element verification (return true or false only)
FORM_FILL, // Event run after the form was filled
}
export default AttributeListeners

View File

@ -1,5 +1,8 @@
import FMAttribute, { FMAttributeListeners, FMAttributeAssignment, TriggerCallback } from "../FMAttribute";
import { evalF } from "../Functions";
import AttributeListeners from "./AttributeListeners";
import AttributeAbstract from "./AttributeAbstract";
import AttributeIdentity from "./Interfaces/AttributeIdentity";
/**
* elements
@ -21,10 +24,10 @@ import { evalF } from "../Functions";
* @implements {FMAClearInterface}
* @implements {FMAFormInitInterface}
*/
export default class FMAutosetAttribute
extends FMAttribute {
public trigger(ev: FMAttributeListeners, datas?: any): void {
console.log("pouet")
export default class AutosetAttribute
extends AttributeAbstract {
public trigger(event: AttributeListeners, data?: any): boolean | void | object {
let str = this.input.element.getAttribute("data-autoset") || ""
if (evalF(str, (ster) => {this.input.setValue(ster)})) return
this.normal(str)
@ -47,13 +50,13 @@ extends FMAttribute {
}
}
public static listeners: FMAttributeListeners[] = [
FMAttributeListeners.CHANGE,
FMAttributeListeners.FORM_FILL
public static listeners: AttributeListeners[] = [
AttributeListeners.CHANGE,
AttributeListeners.FORM_FILL
]
}
export const FMAutosetAttributeAssignment: FMAttributeAssignment = {
attribute: FMAutosetAttribute,
dataElement: "data-autoset"
public static identity: AttributeIdentity = {
attribute: AutosetAttribute,
dataElement: "data-autoset"
}
}

View File

@ -1,5 +1,7 @@
import FMAttribute, { FMAttributeListeners, FMAttributeAssignment } from "../FMAttribute";
import { evalF } from "../Functions";
import AttributeAbstract from "./AttributeAbstract";
import AttributeListeners from "./AttributeListeners";
import AttributeIdentity from "./Interfaces/AttributeIdentity";
/**
* elements
@ -21,9 +23,9 @@ import { evalF } from "../Functions";
* @implements {FMAClearInterface}
* @implements {FMAFormInitInterface}
*/
export default class FMDefaultAttribute
extends FMAttribute {
public trigger(ev: FMAttributeListeners): boolean | void {
export default class DefaultAttribute
extends AttributeAbstract {
public trigger(event: AttributeListeners, data?: any): boolean | void | object {
this.run()
return true
}
@ -69,13 +71,13 @@ extends FMAttribute {
this.input.setValue(attrVal)
}
public static listeners: FMAttributeListeners[] = [
FMAttributeListeners.POST_CLEAR,
FMAttributeListeners.FORM_INIT
public static listeners: AttributeListeners[] = [
AttributeListeners.POST_CLEAR,
AttributeListeners.FORM_INIT
]
}
export const FMDefaultAttributeAssignment: FMAttributeAssignment = {
attribute: FMDefaultAttribute,
dataElement: "data-default"
public static identity: AttributeIdentity = {
attribute: DefaultAttribute,
dataElement: "data-default"
}
}

View File

@ -1,43 +0,0 @@
import FMAttribute, { FMAttributeListeners, FMAttributeAssignment, TriggerCallback } from "../FMAttribute";
/**
* elements
* if input has type and type == type time week
* then it will set the value to a new date of the value
*
*
* ex:
* "child:value:queryselector"
* or
* "child:text:queryselector"
* or
* "child:attributeName:queryselector"
*
*
* @export
* @class FMDefaultAttribute
* @extends {FMAttribute}
* @implements {FMAClearInterface}
* @implements {FMAFormInitInterface}
*/
export default class FMIgnoreAttribute
extends FMAttribute {
public trigger(ev: FMAttributeListeners, datas?: any): TriggerCallback {
console.log("pouetemon")
datas[this.input.getName()] = undefined
console.log(datas)
return {
datas,
result: true
}
}
public static listeners: FMAttributeListeners[] = [
FMAttributeListeners.FORM_SUBMIT
]
}
export const FMIgnoreAttributeAssignment: FMAttributeAssignment = {
attribute: FMIgnoreAttribute,
dataElement: "data-ignore"
}

View File

@ -1,22 +0,0 @@
import FMAttribute, { FMAttributeListeners, FMAttributeAssignment } from "../FMAttribute";
export default class FMRegexAttribute
extends FMAttribute {
public trigger(): boolean {
const regStr = this.input.element.dataset.regex
if (!regStr) return true
const regex = new RegExp(regStr, "g")
const test = this.input.getValue() + ""
console.log(test)
return regex.test(test)
}
public static listeners: FMAttributeListeners[] = [
FMAttributeListeners.VERIFY
]
}
export const FMRegexAttributeAssignment: FMAttributeAssignment = {
attribute: FMRegexAttribute,
dataElement: "data-regex"
}

View File

@ -0,0 +1,44 @@
import FMAttribute, { FMAttributeListeners, FMAttributeAssignment, TriggerCallback } from "../FMAttribute";
import AttributeAbstract from "./AttributeAbstract";
import AttributeListeners from "./AttributeListeners";
import AttributeIdentity from "./Interfaces/AttributeIdentity";
/**
* elements
* if input has type and type == type time week
* then it will set the value to a new date of the value
*
*
* ex:
* "child:value:queryselector"
* or
* "child:text:queryselector"
* or
* "child:attributeName:queryselector"
*
*
* @export
* @class FMDefaultAttribute
* @extends {FMAttribute}
* @implements {FMAClearInterface}
* @implements {FMAFormInitInterface}
*/
export default class IgnoreAttribute
extends AttributeAbstract {
public trigger(event: AttributeListeners, data?: any): boolean | void | object {
console.log("pouetemon")
data[this.input.getName()] = undefined
console.log(data)
return data
}
public static listeners: AttributeListeners[] = [
AttributeListeners.FORM_SUBMIT
]
public static identity: AttributeIdentity = {
attribute: IgnoreAttribute,
dataElement: "data-ignore"
}
}

View File

@ -0,0 +1,6 @@
import AttributeInterface from "./AttributeInterface"
export default interface AttributeIdentity {
attribute: AttributeInterface,
dataElement: string
}

View File

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

View File

@ -0,0 +1,24 @@
import AttributeIdentity from './Interfaces/AttributeIdentity';
import AttributeAbstract from './AttributeAbstract';
import AttributeListeners from "./AttributeListeners";
export default class RegexAttribute
extends AttributeAbstract {
public trigger(): boolean {
const regStr = this.input.element.dataset.regex
if (!regStr) return true
const regex = new RegExp(regStr, "g")
const test = this.input.getValue() + ""
console.log(test)
return regex.test(test)
}
public static listeners: AttributeListeners[] = [
AttributeListeners.VERIFY
]
public static identity: AttributeIdentity = {
attribute: RegexAttribute,
dataElement: "data-regex"
}
}

View File

@ -1,18 +1,18 @@
import { InputAssignment } from '../Interfaces';
import FormManager from "../FormManager"
import FMInput from "../FMInput"
import InputIdentity from './Interfaces/InputIdentity';
import DefaultInput from './DefaultInput';
/**
* the upgraded datalist element
* @class FMDatalistInput
* @extends {FMInput}
*/
export default class FMDatalistInput extends FMInput {
export default class DatalistInput extends DefaultInput {
datalist: HTMLDataListElement
isStrict: boolean
constructor(element: HTMLInputElement, form: FormManager) {
constructor(element: HTMLElement, form: FormManager) {
super(element, form)
// check if input is strict on inputs
@ -62,10 +62,11 @@ export default class FMDatalistInput extends FMInput {
// if strict return undefined else return element value
return this.isStrict ? undefined : this.formatValue(this.element.value)
}
}
export const FMDatalistAssignement: InputAssignment = {
input: FMDatalistInput,
attributes: "list",
tagName: "input"
public static identity: InputIdentity = {
input: DatalistInput,
attributes: "list",
tagName: "input"
}
}

View File

@ -1,44 +1,44 @@
import { InputAssignment } from '../Interfaces';
import FMInput from "../FMInput"
import InputIdentity from './Interfaces/InputIdentity'
import DefaultInput from './DefaultInput'
/**
*
* @class FMDateInput
* @extends {FMInput}
*/
export default class FMDateInput extends FMInput {
export default class DateInput extends DefaultInput {
setValue(value: any) {
public setValue(value: any) {
// handle GO null value
const format = this.formatValue(value)
if (format) {
this.element.valueAsDate = format
}
this.element.value = format
this.element.value = ""
}
getValue(): Date|undefined {
public getValue(): Date|undefined {
// if get date and if null return undefined else return value
let date = this.element.valueAsDate
return date == null ? undefined : date
}
public formatValue(val: any): Date|undefined {
if (typeof val === "object" && typeof val.getDate === "function") {
return (val as Date)
}
if (val === "0001-01-01T00:00:00Z") {
return undefined
}
if (typeof val === "string" || typeof val === "number") {
return new Date(val)
}
if (typeof val === "object" && typeof val.getDate === "function") {
return (val as Date)
}
return undefined
}
}
export const FMDateAssignement: InputAssignment = {
input: FMDateInput,
type: "date",
tagName: "input"
public static identity: InputIdentity = {
input: DateInput,
type: "date",
tagName: "input"
}
}

View File

@ -0,0 +1,39 @@
import { realType } from "../Functions"
import InputAbstract from "./InputAbstract"
import InputIdentity from "./Interfaces/InputIdentity"
export default class DefaultInput extends InputAbstract {
public setValue(value: any) {
this.element.value = this.formatValue(value)
}
public getValue(): any {
return this.formatValue(this.element.value)
}
public formatValue(value: any): any {
// if the value is a number return it as a number obj
return realType(value)
}
public getName(): string {
// while we search for inputs containing [name] we search for the input real name in [name] or [data-name]
// (Allow other inputs to play with inputs)
let attr = this.element.getAttribute("name") || this.element.dataset.name;
if (attr) return attr
throw Error("Error: could not get input name!")
}
public verify(): boolean {
let val: any = this.getValue()
// if element is required and value is undefined retur false
if (this.element.hasAttribute("required") && (val === undefined || val === null || val === "")) return false
return true
}
public static identity: InputIdentity = {
input: DefaultInput
}
}

View File

@ -1,13 +1,13 @@
import { InputAssignment } from '../Interfaces';
import FMInput from "../FMInput"
import FormManager from '../FormManager';
import DefaultInput from './DefaultInput';
import InputIdentity from './Interfaces/InputIdentity';
/**
*
* @class FMFileInput
* @extends {FMInput}
*/
export default class FMFileInput extends FMInput {
export default class FileInput extends DefaultInput {
isUploaded = false
@ -15,16 +15,16 @@ export default class FMFileInput extends FMInput {
button: HTMLButtonElement
button: HTMLButtonElement|undefined
constructor(element: HTMLInputElement, form: FormManager) {
constructor(element: HTMLElement, form: FormManager) {
super(element, form)
this.type = this.element.dataset.uploadType ? parseInt(this.element.dataset.uploadType): 1
element.addEventListener("change", () => {
console.log("pouet")
let files = element.files
let files = this.element.files
if (files && element.parentElement && files.length > 0) {
const name = element.parentElement.querySelector(".file-name")
if (name) name.textContent = files[0].name
@ -109,10 +109,10 @@ export default class FMFileInput extends FMInput {
return true
}
}
public static identity: InputIdentity = {
input: FileInput,
type: "file",
tagName: "input"
}
export const FMFileAssignement: InputAssignment = {
input: FMFileInput,
type: "file",
tagName: "input"
}

View File

@ -0,0 +1,64 @@
import FormManager from "../FormManager";
import InputIdentity from "./Interfaces/InputIdentity";
export default abstract class InputAbstract {
public element: HTMLInputElement
public form: FormManager
public constructor(element: HTMLElement, form: FormManager) {
this.element = element as HTMLInputElement
this.form = form
}
/**
* Set the element Value
*
* _hint: pass it through this.formatValue_
*
* @param {*} value the input value
* @memberof FMInput
*/
public abstract setValue(value: any): void
/**
* Get the element value
*
* @returns {*} the value
* @memberof FMInput
*/
public abstract getValue(): any
/**
* Format the value into a usable one by the module
*
* for elements like `select` if the value don't correspond to something
* it will return the default `value`
*
* @param {*} value
* @returns {*}
* @memberof FMInput
*/
public abstract formatValue(value: any): any
/**
* Retrieve the input name
*
* name can be located at multiple locations like `name` attribute or `data-name` attribute
*
* @returns {string}
* @memberof FMInput
*/
public abstract getName(): string
/**
* Verify if the element is correct
*
* @returns {boolean}
* @memberof FMInput
*/
public abstract verify(): boolean
public static identity: InputIdentity
}

View File

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

View File

@ -0,0 +1,43 @@
import InputAbstract from "../InputAbstract";
import FMDatalistInput from "../FMDatalistInput";
import FMDateInput from "../FMDateInput";
import DefaultInput from "../DefaultInput";
import FormManager from "../../FormManager";
interface InputConstructor {
new(element: HTMLElement, form: FormManager): InputAbstract
}
/**
* Make an Input class different with the othes ones
*/
export default interface InputIdentity {
/**
* The input
*/
input: InputConstructor
/**
* the classes filters
*/
classes?: string[] | string
/**
* The Attribute filters
*/
attributes?: string[] | string
/**
* If it's an Input the type have to cerrespond
* to this
*/
type?: string
/**
* the TagName used
*
* ex: `<div></div>` will be `DIV`
*/
tagName ?: string
}

View File

@ -1,21 +1,22 @@
import { InputAssignment } from './../Interfaces';
import FormManager from "../FormManager"
import FMInput from "../FMInput"
import DefaultInput from './DefaultInput';
import InputAbstract from './InputAbstract';
import InputIdentity from './Interfaces/InputIdentity';
/**
*
* @class FMRepeatInput
* @extends {FMInput}
*/
export default class FMRepeatInput extends FMInput {
export default class RepeatInput extends DefaultInput {
elements: FMInput[][] = []
elements: InputAbstract[][] = []
private template: HTMLElement
private addBtn: HTMLElement
constructor(element: HTMLDivElement, form: FormManager) {
constructor(element: HTMLElement, form: FormManager) {
super(element, form)
//fetch Template
@ -65,8 +66,8 @@ export default class FMRepeatInput extends FMInput {
node.style.display = ""
// loop through inputs ot init them
let sub: FMInput[] = []
node.querySelectorAll("[data-input]").forEach((el: Element) => {
let sub: InputAbstract[] = [];
(node.querySelectorAll("[data-input]") as NodeListOf<HTMLElement>).forEach((el: HTMLElement) => {
let input = this.form.getInit(el)
if (!input) {
return
@ -143,10 +144,10 @@ export default class FMRepeatInput extends FMInput {
}
return values
}
}
export const FMRepeatAssignment: InputAssignment = {
input: FMRepeatInput,
classes: "fm-repeat",
tagName: "div"
public static identity: InputIdentity = {
input: RepeatInput,
classes: "fm-repeat",
tagName: "div"
}
}

View File

@ -1,5 +1,5 @@
import { InputAssignment } from '../Interfaces';
import FMInput from "../FMInput"
import InputIdentity from './Interfaces/InputIdentity';
import DefaultInput from './DefaultInput';
import { realType } from '../Functions';
/**
@ -7,7 +7,7 @@ import { realType } from '../Functions';
* @class FMDateInput
* @extends {FMInput}
*/
export default class FMSelectInput extends FMInput {
export default class SelectInput extends DefaultInput {
public formatValue(val: any): any {
const opt = this.element.querySelector(`option[value="${val}"]`) || this.element.querySelector("option[selected]")
@ -16,9 +16,9 @@ export default class FMSelectInput extends FMInput {
}
return undefined
}
}
export const FMSelectAssignement: InputAssignment = {
input: FMSelectInput,
tagName: "select"
public static identity: InputIdentity = {
input: SelectInput,
tagName: "select"
}
}