import React from "react"; import PropTypes from "prop-types"; import { Input, Textarea, Select, Enabler } from "./"; import { FormObjToJSON, format, autocomplete, notify } from "../helpers/"; import { t } from "../locales/"; import "./formbuilder.scss"; export class FormBuilder extends React.Component { constructor(props) { super(props); } section(struct, key, level = 0) { if (struct == null) struct = ""; const isALeaf = function(struct) { if ("label" in struct && "type" in struct && "value" in struct && "default" in struct) { return true; } return false; }; if (Array.isArray(struct)) return null; else if (isALeaf(struct) === false) { const [normal, advanced] = function(s) { const _normal = []; const _advanced = []; for (const key in s) { const tmp = { key: key, data: s[key] }; "id" in s[key] ? _advanced.push(tmp) : _normal.push(tmp); } return [_normal, _advanced]; }(struct); if (level <= 1) { return (
{ key ?

{ format(key) }

: "" } { normal.map((s, index) => { return (
{ this.section(s.data, s.key, level + 1) }
); }) }
{ advanced.map((s, index) => { return (
{ this.section(s.data, s.key, level + 1) }
); }) }
); } return (
{ format(key) } { Object.keys(struct).map((key, index) => { return (
{ this.section(struct[key], key, level + 1) }
); }) }
); } const id = {}; let target = []; if (struct.id !== undefined) { id.id = this.props.idx === undefined ? struct.id : struct.id + "_" + this.props.idx; } if (struct.type === "enable") { target = struct.target.map((target) => { return this.props.idx === undefined ? target : target + "_" + this.props.idx; }); } const onChange = function(e, fn) { struct.value = e; if (typeof fn === "function") { fn(struct); } this.props.onChange.call( this, FormObjToJSON(this.props.form), ); }; return ( ); } render() { return this.section(this.props.form || {}); } } const FormElement = (props) => { const id = props.id !== undefined ? { id: props.id } : {}; const struct = props.params; let $input = ( props.onChange(e.target.value)} {...id} name={struct.label} type="text" defaultValue={struct.value} placeholder={ t(struct.placeholder) } /> ); switch (props.params["type"]) { case "text": { const onTextChange = (value) => { if (value === "") { value = null; } props.onChange(value); }; const list_id = struct.datalist ? "list_"+Math.random() : null; $input = ( onTextChange(e.target.value)} {...id} name={struct.label} type="text" value={struct.value || ""} placeholder={ t(struct.placeholder) } readOnly={struct.readonly} autoComplete="off" autoCorrect="off" autoCapitalize="off" spellCheck="false" /> ); if (list_id != null) { const filtered = function(multi, datalist, currentValue) { if (multi !== true || currentValue == null) return datalist; return autocomplete( currentValue .split(",") .map((t) => t.trim()) .filter((t) => t), datalist, ); }; $input = ( { $input } { filtered(struct.multi, struct.datalist, struct.value).map((item, i) => { return ( ); } break; } case "number": { const onNumberChange = (value) => { value = value === "" ? null : parseInt(value); props.onChange(value); }; $input = ( onNumberChange(e.target.value)} {...id} name={struct.label} type="number" value={struct.value === null ? "" : struct.value} placeholder={ t(struct.placeholder) } /> ); break; } case "password": { const onPasswordChange = (value) => { if (value === "") { value = null; } props.onChange(value); }; $input = ( onPasswordChange(e.target.value)} {...id} name={struct.label} type="password" value={struct.value || ""} placeholder={ t(struct.placeholder) } autoComplete="off" autoCorrect="off" autoCapitalize="off" spellCheck="false"/> ); break; } case "long_password": { const onLongPasswordChange = (value) => { if (value === "") { value = null; } props.onChange(value); }; $input = (