import { customElement, html, TemplateResult, DeesElement } from '@designestate/dees-element'; import * as domtools from '@designestate/dees-domtools'; import { DeesInputCheckbox } from './dees-input-checkbox.js'; import { DeesInputText } from './dees-input-text.js'; import { DeesInputQuantitySelector } from './dees-input-quantityselector.js'; import { DeesInputRadio } from './dees-input-radio.js'; import { DeesFormSubmit } from './dees-form-submit.js'; export type TFormElement = Array< DeesInputCheckbox | DeesInputText | DeesInputQuantitySelector | DeesInputRadio >; declare global { interface HTMLElementTagNameMap { 'dees-form': DeesForm; } } @customElement('dees-form') export class DeesForm extends DeesElement { public static demo = () => html` { const form: DeesForm = eventArg.currentTarget; form.setStatus('pending', 'authenticating...'); await domtools.plugins.smartdelay.delayFor(1000); form.setStatus('success', 'authenticated!'); }} > Submit `; public name: string = 'myform'; public changeSubject = new domtools.rxjs.Subject(); public render(): TemplateResult { return html` `; } public async firstUpdated() { const formChildren = this.getFormChildren(); this.checkRequiredStatus(); for (const child of formChildren) { child.changeSubject.subscribe(async (elementArg: TFormElement) => { const valueObject = await this.gatherData(); this.changeSubject.next(valueObject); console.log(valueObject); this.checkRequiredStatus(); }); } await this.instrumentBehaviours(); } public getFormChildren() { const children: Array = this.children as any; const formChildren: TFormElement = []; for (const child of children) { if ( child instanceof DeesInputCheckbox || child instanceof DeesInputText || child instanceof DeesInputQuantitySelector ) { formChildren.push(child); } } return formChildren; } public getSubmitButton() { const children: Array = this.children as any; let submitButton: DeesFormSubmit; for (const childArg of children) { if (childArg instanceof DeesFormSubmit) { submitButton = childArg; } } return submitButton; } public async checkRequiredStatus() { console.log('checking the required status.'); let requiredOK = true; for (const childArg of this.getFormChildren()) { if (childArg.required && !childArg.value) { requiredOK = false; } } if (this.getSubmitButton()) { this.getSubmitButton().disabled = !requiredOK; } } public async gatherData() { const children = this.getFormChildren(); const valueObject: { [key: string]: string | number | boolean } = {}; for (const child of children) { valueObject[child.key] = child.value; } return valueObject; } public async gatherAndDispatch() { const valueObject = await this.gatherData(); const formDataEvent = new CustomEvent('formData', { detail: { data: valueObject, }, bubbles: true, }); this.dispatchEvent(formDataEvent); console.log('dispatched data:'); console.log(valueObject); } public setStatus( visualStateArg: 'normal' | 'pending' | 'error' | 'success', textStateArg: string ) { const inputChildren = this.getFormChildren(); const submitButton = this.getSubmitButton(); switch (visualStateArg) { case 'normal': submitButton.disabled = false; submitButton.status = 'normal'; for (const inputChild of inputChildren) { inputChild.disabled = false; } break; case 'pending': submitButton.disabled = true; submitButton.status = 'pending'; for (const inputChild of inputChildren) { inputChild.disabled = true; } break; case 'success': submitButton.disabled = true; submitButton.status = 'success'; for (const inputChild of inputChildren) { inputChild.disabled = true; } break; case 'error': submitButton.disabled = true; submitButton.status = 'error'; for (const inputChild of inputChildren) { inputChild.disabled = true; } break; } submitButton.text = textStateArg; } public async instrumentBehaviours() { const children = this.getFormChildren(); for (const child of children) { child.addEventListener('keydown', (eventArg) => { if (eventArg.key === 'Enter') { const currentIndex = children.indexOf(child); if (currentIndex < children.length - 1) { children[currentIndex + 1].focus(); } else { children[currentIndex].blur(); this.getSubmitButton().focus(); } } }); } } }