mirror of
https://github.com/dzeiocom/FormManager.git
synced 2025-04-22 19:02:15 +00:00
Moved objects
This commit is contained in:
parent
135f6aa770
commit
dc40b373ff
@ -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/),
|
||||
|
@ -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[]
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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)
|
||||
public assign(...inter: (typeof InputAbstract[])) {
|
||||
for (const input of inter) {
|
||||
this.FMInputs.unshift(input.identity)
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign a single Module
|
||||
*
|
||||
* @param {FMAssignInterface} inter
|
||||
* @memberof FormManager
|
||||
*/
|
||||
public assignSingle(inter: InputAssignment) {
|
||||
this.FMInputs.unshift(inter)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
23
src/attributes/AttributeAbstract.ts
Normal file
23
src/attributes/AttributeAbstract.ts
Normal 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
|
||||
}
|
11
src/attributes/AttributeListeners.ts
Normal file
11
src/attributes/AttributeListeners.ts
Normal 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
|
@ -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,
|
||||
public static identity: AttributeIdentity = {
|
||||
attribute: AutosetAttribute,
|
||||
dataElement: "data-autoset"
|
||||
}
|
||||
}
|
@ -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,
|
||||
public static identity: AttributeIdentity = {
|
||||
attribute: DefaultAttribute,
|
||||
dataElement: "data-default"
|
||||
}
|
||||
}
|
@ -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"
|
||||
}
|
@ -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"
|
||||
}
|
44
src/attributes/IgnoreAttribute.ts
Normal file
44
src/attributes/IgnoreAttribute.ts
Normal 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"
|
||||
|
||||
}
|
||||
}
|
6
src/attributes/Interfaces/AttributeIdentity.ts
Normal file
6
src/attributes/Interfaces/AttributeIdentity.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import AttributeInterface from "./AttributeInterface"
|
||||
|
||||
export default interface AttributeIdentity {
|
||||
attribute: AttributeInterface,
|
||||
dataElement: string
|
||||
}
|
13
src/attributes/Interfaces/AttributeInterface.ts
Normal file
13
src/attributes/Interfaces/AttributeInterface.ts
Normal 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
|
||||
}
|
24
src/attributes/RegexAttribute.ts
Normal file
24
src/attributes/RegexAttribute.ts
Normal 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"
|
||||
}
|
||||
}
|
@ -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,
|
||||
public static identity: InputIdentity = {
|
||||
input: DatalistInput,
|
||||
attributes: "list",
|
||||
tagName: "input"
|
||||
}
|
||||
|
||||
}
|
@ -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,
|
||||
public static identity: InputIdentity = {
|
||||
input: DateInput,
|
||||
type: "date",
|
||||
tagName: "input"
|
||||
}
|
||||
}
|
39
src/modules/DefaultInput.ts
Normal file
39
src/modules/DefaultInput.ts
Normal 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
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const FMFileAssignement: InputAssignment = {
|
||||
input: FMFileInput,
|
||||
public static identity: InputIdentity = {
|
||||
input: FileInput,
|
||||
type: "file",
|
||||
tagName: "input"
|
||||
}
|
||||
|
||||
}
|
64
src/modules/InputAbstract.ts
Normal file
64
src/modules/InputAbstract.ts
Normal 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
|
||||
}
|
10
src/modules/Interfaces/InputArray.ts
Normal file
10
src/modules/Interfaces/InputArray.ts
Normal 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
|
||||
}
|
43
src/modules/Interfaces/InputIdentity.ts
Normal file
43
src/modules/Interfaces/InputIdentity.ts
Normal 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
|
||||
}
|
@ -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,
|
||||
public static identity: InputIdentity = {
|
||||
input: RepeatInput,
|
||||
classes: "fm-repeat",
|
||||
tagName: "div"
|
||||
}
|
||||
}
|
@ -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,
|
||||
public static identity: InputIdentity = {
|
||||
input: SelectInput,
|
||||
tagName: "select"
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user