import m from "mithril" export interface iForm { onchanged?: (e:Event) => void onsubmit: (form:HTMLFormElement) => boolean oncancel: (e:Event) => void showbuttons?: boolean /** Die Funktion gibt das HTMLFormElement zurück, welches in der Form-Componente angelegt wird */ onformcreate?: (form:HTMLFormElement) => void } export const Form:m.ClosureComponent = (vnode) => { let form: HTMLFormElement let isDirty: boolean = false let showButtons: boolean = vnode.attrs.showbuttons == undefined ? true : vnode.attrs.showbuttons function canCloseForm(typ: string = "") { if (!isDirty) { return true } let text = (typ == "reset") ? "zurücksetzen" : "beenden" return confirm (`Das Formular enthält noch ungespeicherte Eingaben. Wollen Sie das Formular trotzdem ${text}?`) } function onchanged (e:Event) { isDirty = true if (vnode.attrs.onchanged != undefined) { vnode.attrs.onchanged(e) } } function submit (e:Event) { e.preventDefault() if (vnode.attrs.onsubmit(form) == true) { isDirty = false } } function registerFormElement (f:HTMLFormElement) { if (vnode.attrs.onformcreate != undefined) { vnode.attrs.onformcreate(f) } } function cancel(e:Event) { e.preventDefault() if (canCloseForm() == true) { isDirty = false if (vnode.attrs.oncancel != undefined) { vnode.attrs.oncancel(e) } else { history.back() } } else { e['redraw'] = false } } function reset(e:Event) { if (canCloseForm("reset")) { isDirty = false // Hier passiert nichts. // Da mithril nach jedem User-Event (wie z.B. einem 'Click') ein redraw() ausführt, wird hier die Form // neu gezeichnet und zwar mit den ursprünglichen Daten aus den zu grundeliegenden Datenmodel, das ja // ohne submit noch nicht geändert wurde. return } e['redraw'] = false return } return { onremove: (vnode) => { let message = "remove" if (isDirty) { message += " isDirty" } console.log(message) }, view: (vnode) => { return m("form", { onreset: () => {console.log("reset")}, onsubmit: submit, oncreate: (vnode) => { form = vnode.dom as HTMLFormElement let elements = form.querySelectorAll("input,textarea") for (let index = 0; index < elements.length; index++) { const element = elements[index]; element.addEventListener("change", onchanged) } registerFormElement(form) } }, vnode.children, showButtons == true ? m("div.w3-bar.w3-padding-16",[ m("button.w3-button.w3-theme.w3-right.w3-mobile", {style: {margin: '0px 0px 2px 4px'}, type: "submit"}, "Speichern"), m("button.w3-button.w3-theme.w3-right.w3-mobile", {style: {margin: '0px 0px 2px 4px'}, onclick: cancel, type: "button"}, "Abbrechen"), m("button.w3-button.w3-theme.w3-right.w3-mobile", {onclick: reset, type: "button"}, "Zurücksetzen") ]) : null ) } } } export interface iFormBorder { maxwidth: string } export const FormBorder: m.Component = { view: (vnode) => { let mw:string = vnode.attrs.maxwidth === undefined ? "600px" : vnode.attrs.maxwidth return m("div.w3-border.w3-border-theme.w3-container.w3-content.w3-margin-top", {style: {'max-width': mw, 'box-shadow': '3px 3px 3px darkgrey'}}, vnode.children) } }