Form.tsx
134 lines
| 3.9 KiB
| text/x-typescript
|
TypeScriptLexer
cin
|
r134 | |||
import { djbase, djclass } from "../declare"; | ||||
import { attach, createElement } from "../tsx"; | ||||
import { DjxWidgetBase } from "../tsx/DjxWidgetBase"; | ||||
import _FormMixin from "./_FormMixin"; | ||||
/** This widget represents a document section containing interactive controls | ||||
* for submitting information. | ||||
*/ | ||||
@djclass | ||||
export default class Form<T extends object> extends djbase(DjxWidgetBase, _FormMixin) { | ||||
/** Name of form for scripting. */ | ||||
name?: string; | ||||
/** The URL that processes the form submission. */ | ||||
action?: string; | ||||
/** The HTTP method to submit the form with. */ | ||||
method?: "POST" | "GET" | "DIALOG"; | ||||
/** If the value of the method attribute is post, enctype is the MIME type | ||||
* of the form submission. | ||||
*/ | ||||
enctype?: string; | ||||
/** Comma-separated content types the server accepts. | ||||
* | ||||
* @deprecated This attribute has been deprecated and should not be used. | ||||
* Instead, use the accept attribute on <input type=file> elements. | ||||
*/ | ||||
accept?: string; | ||||
/** Space-separated character encodings the server accepts. The browser | ||||
* uses them in the order in which they are listed. | ||||
*/ | ||||
"accept-charset"?: string; | ||||
/** Indicates where to display the response after submitting the form. It | ||||
* is a name/keyword for a browsing context (for example, tab, window, or | ||||
* iframe). | ||||
*/ | ||||
target?: string; | ||||
/** Indicates whether input elements can by default have their values | ||||
* automatically completed by the browser. `autocomplete` attributes on form | ||||
* elements override it on `<form>`. | ||||
*/ | ||||
autocomplete?: "off" | "on"; | ||||
/** This Boolean attribute indicates that the form shouldn't be validated | ||||
* when submitted. If this attribute is not set the form is validated, it | ||||
* can be overridden by a `formnovalidate` attribute on a `<button>`, | ||||
* `<input type="submit">`, or `<input type="image">` element belonging to | ||||
* the form. | ||||
*/ | ||||
novalidate?: boolean; | ||||
value?: T; | ||||
containerNode?: HTMLFormElement; | ||||
_resetting = false; | ||||
constructor(opts?: Partial<Form<T>>, srcRef?: string | Node) { | ||||
super(opts, srcRef); | ||||
} | ||||
render() { | ||||
return <form onreset={this._onReset} onsubmit={this._onSubmit} ref={attach(this, "containerNode")}> | ||||
</form>; | ||||
} | ||||
postCreate() { | ||||
super.postCreate(); | ||||
this.watch("value", (_prop, _oldValue, newValue) => this.onValueChange(newValue)); | ||||
} | ||||
private readonly _onReset = (evt: Event) => { | ||||
if (!this._resetting) { | ||||
// re-dispatch event to replace default reset behavior | ||||
try { | ||||
this._resetting = true; | ||||
evt.preventDefault(); | ||||
if(this.containerNode?.dispatchEvent(new Event(evt.type, evt))) | ||||
super.reset(); | ||||
} finally { | ||||
this._resetting = false; | ||||
} | ||||
} else { | ||||
this.onReset(evt); | ||||
} | ||||
}; | ||||
private readonly _onSubmit = (evt: SubmitEvent) => { | ||||
if(!this.novalidate && !this.validate()) { | ||||
evt.preventDefault(); | ||||
evt.stopPropagation(); | ||||
} else { | ||||
this.onSubmit(evt); | ||||
} | ||||
}; | ||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||||
onSubmit(evt: Event) { | ||||
} | ||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||||
onReset(evt: Event) { | ||||
} | ||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||||
onValueChange(value?: T) { | ||||
} | ||||
/** Resets the form. */ | ||||
reset() { | ||||
if (!this.containerNode) | ||||
throw new Error("Can't reset the destroyed form"); | ||||
this.containerNode.reset(); | ||||
} | ||||
/** Programmatically submits form, no additional events emitted | ||||
* or checks made. | ||||
*/ | ||||
submit() { | ||||
if (!this.containerNode) | ||||
throw new Error("Can't submit the destroyed form"); | ||||
this.containerNode.submit(); | ||||
} | ||||
} | ||||