Last active
June 4, 2021 06:25
-
-
Save Parables/44ba43273a393a0ec4ee7c6c7ed6ea26 to your computer and use it in GitHub Desktop.
This builds a Form using Flexbox where fields are arranged in a row, many rows make a section, many sections makes up the form
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| interface IForm { | |
| id: string | |
| sections: any[] | |
| classNames?: string | |
| store?: any | |
| validator?: any | |
| } | |
| export type FieldType = "text" | "email" | "password" | "tel" | "date" | "time" | "number" | | |
| "typeahead" | "radio" | "checkbox" | "checklist" | "chip" | "chipinput" | "select" | | |
| "range-time" | "range-date" | "range-number" | "repeatField" | |
| export interface IField { | |
| id: string | |
| name: string | |
| label?: string | |
| type?: FieldType | |
| placeholder?: string | |
| colors?: any | |
| width?: string | |
| height?: string | |
| margin?: string | |
| min?: number | |
| max?: number | |
| step?: number | |
| items?: Item[] | any[] | string[] | |
| passwordChar?: string | |
| multiSelect?: boolean | |
| readonly?: boolean | |
| variant?: "outlined" | "material" | "default" | |
| // mask?: IMask | |
| validate?: string[] | |
| startIcon?: boolean | |
| endIcon?: boolean | |
| validators?: any[] | |
| } | |
| export interface Item { | |
| id: string | |
| name: string | |
| value: string | |
| label?: string | |
| } | |
| class Form implements IForm { | |
| id: string = "" | |
| sections: Section[] = [] | |
| classNames?: string = "" | |
| store?: any | |
| validator?: any | |
| constructor(props: IForm) { | |
| this.id = props.id | |
| this.sections = props.sections | |
| this.classNames = props.classNames | |
| this.store = props.store | |
| this.validator = props.validator | |
| } | |
| static from({ ...options }: IForm) { | |
| return new Form({ ...options }) | |
| } | |
| getSection(section: Section) { | |
| return this.sections.findIndex((s) => Object.is(s, section)); | |
| } | |
| addSection(section: ISection, insertAt?: number) { | |
| let newSection = new Section({ ...section }) | |
| this.sections = getSelection(newSection)<-1? this.sections.slice(): insertAt ? [...this.sections.slice(0, insertAt), newSection, ...this.sections.slice(insertAt)] : [...this.sections, newSection]; | |
| return this.sections; | |
| } | |
| removeSection(section: ISection, removeAt?: number) { | |
| if (section && !removeAt) removeAt = this.getSection(new Section({ ...section })); | |
| this.sections = [...this.sections.slice(0, removeAt), ...this.sections.slice(removeAt)]; | |
| return this.sections; | |
| } | |
| print() { | |
| let form = { ...this } | |
| console.log(form) | |
| return form | |
| } | |
| } | |
| export interface ISection { | |
| title?: string | |
| classNames?: string | |
| rows: Row[] | |
| } | |
| export class Section implements ISection { | |
| title?: string = "" | |
| classNames?: string = "" | |
| rows: Row[] = [] | |
| constructor(props: ISection) { | |
| this.title = props.title | |
| this.classNames = props.classNames | |
| this.rows = props.rows | |
| } | |
| getRow(row: IRow) { | |
| return this.rows.findIndex((r) => Object.is(r, row)); | |
| } | |
| addRow(row: IRow, insertAt?: number) { | |
| let { rows } = this.section; | |
| let newRow = new Row({ ...row }) | |
| // rows = insertAt ? [...rows.slice(0, insertAt), newRow, ...rows.slice(insertAt)] : [...rows, newRow]; | |
| this.section.rows.push(newRow) //= rows; | |
| // return this.section.rows; | |
| } | |
| removeRow(row: IRow, removeAt?: number) { | |
| let { rows } = this.section; | |
| if (row && !removeAt) | |
| removeAt = this.getRow(row); | |
| rows = [...rows.slice(0, removeAt), ...rows.slice(removeAt)]; | |
| this.section.rows = rows; | |
| return this.section.rows; | |
| } | |
| } | |
| export interface IRow { | |
| classNames?: string | |
| fields: Field[] | |
| rowStyle?: "block" | "inline" | |
| rowHeader?: string | |
| } | |
| class Row { | |
| constructor(public row: IRow) { } | |
| getFields(field: IField) { | |
| let { fields } = this.row; | |
| return fields.findIndex((f) => Object.is(f, field)); | |
| } | |
| addField(field: IField, insertAt?: number) { | |
| let { fields } = this.row; | |
| let newField = new Field({ ...field }) | |
| fields = insertAt ? [...fields.slice(0, insertAt), newField, ...fields.slice(insertAt)] : [...fields, newField]; | |
| this.row.fields = fields; | |
| return this.row.fields; | |
| } | |
| removefield(field?: IField, removeAt?: number) { | |
| let { fields } = this.row; | |
| if (field && !removeAt) | |
| removeAt = this.getFields(field); | |
| fields = [...fields.slice(0, removeAt), ...fields.slice(removeAt)]; | |
| this.row.fields = fields; | |
| return this.row.fields; | |
| } | |
| } | |
| class Field { | |
| constructor(public field: IField) { } | |
| } | |
| let form = new Form({ id: "Test Form", sections: [] }) | |
| form.addSection("Item One") | |
| form.print() |
Author
Hello @foxy980, do you have any interest in this gist?. I am building a Dynamic Form Builder as part of Svelta (my copy-paste UI components kit for Svelte).
This gist is deprecated: please see it in action here or get the Typescript version here
The updated version of this gist is here.
Please note I am still working on it so its a little disorganised.
Please check that out and let me know if you have any issues
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
wow