super-form
Submit AJAX requests with HTML forms. Pair it with Quark to render the response.
Features
- Makes AJAX requests JSON payload is built from each input's
nameandtypeattributes - Progressively enhanced Doesn't replace the native
form; it enhances it. Everything you know aboutformandinputstill applies. - Provides data Use Quark to render the response
- Submit command
--submitsubmits programmatically (<button command="--submit" commandfor="…">) - Highly configurable Headers, credentials, redirect, etc
Installation
This package is available in the
<script src="https://unpkg.com/@excom/kit-utils@0.3.0/dist/index.umd.min.js"></script>
<script src="https://unpkg.com/@excom/neutron@0.2.0/dist/index.umd.min.js"></script>
<script src="https://unpkg.com/@excom/super-form@0.1.8/dist/index.umd.min.js"></script>npm install @excom/super-form<!-- import path to `node_modules` will depend on your build setup -->
<script type="module" src="/node_modules/@excom/super-form"></script>
<link rel="stylesheet" href="/node_modules/@excom/super-form">import "@excom/super-form";Peer dependencies (0)
Packages a consumer must install alongside this one. Workspace deps are bundled.
| Package | Version |
|---|---|
|
Usage
Just wrap a regular form. Form fields become a JSON payload via their name: dot-separated names nest, and a trailing [] collects same-named fields into an array. input[type] determines the type conversion.
<super-form>
<form action="/api/signup" method="post">
<input name="isAvailable" type="checkbox"> <!-- -> { isAvailable: true } -->
<input name="address.city" value="Anytown"> <!-- -> { address: { city: "Anytown" } } -->
<input name="tags[]" value="smart">
<input name="tags[]" value="kind"> <!-- -> { tags: ["smart", "kind"] } -->
<button type="submit">Sign up</button>
</form>
</super-form><super-form>
<form action="/api/signup" method="post">
<input name="isAvailable" type="checkbox"> <!-- -> { isAvailable: true } -->
<input name="address.city" value="Anytown"> <!-- -> { address: { city: "Anytown" } } -->
<input name="tags[]" value="smart">
<input name="tags[]" value="kind"> <!-- -> { tags: ["smart", "kind"] } -->
<button type="submit">Sign up</button>
</form>
</super-form>Hook the lifecycle state with CSS:
super-form[is-loading] { /* form currently submitting, show loading spinner */ }
super-form[is-error]::before { content: "An error occurred." }super-form[is-loading] { /* form currently submitting, show loading spinner */ }
super-form[is-error]::before { content: "An error occurred." }did-load is set on the first success, kept through a resubmit (where is-loading replaces is-success) and cleared on an error: gate content on [did-load] to keep it on screen during a resubmit.
Or Quark:
super-form[is-success] {
$res: prop("provision").body;
span { content: $res.json.email; }
}super-form[is-success] {
$res: prop("provision").body;
span { content: $res.json.email; }
}API Reference
Attributes
Role —option is configurable, state
is managed by the element (read-only), or hybrid which is both.
Provision
Thisprovision property lives on the DOM node.
Read / watch it with Quark’s prop("provision"), or listen
for the neutron-provision event from app JS.
Events
Type
command event (HTML Command API): from a
<button command commandfor>, an <event-handler
command-name>, or a CommandEvent.
Recognized Elements
Child or descendant elements are recognized by and relevant to its functionality.Styles
@custom-selector synonyms so custom elements can share
semantic styles. Element aliases match the host tag / .tag-* class; state
aliases match attributes (nested under the element alias).
super-form
Attributes (13)
Role —option is configurable, state
is managed by the element (read-only), or hybrid which is both.
api-method
apiMethod
string
"GET"api-url
form-ref or custom doFetch() args) is merged in as query params instead.
apiUrl
string
""fetch-credentials
RequestInit.credentials mode.
fetchCredentials
string
"omit" | "same-origin" | "include""include"fetch-redirect
RequestInit.redirect mode. Unset defers to the browser default (follow).
fetchRedirect
string
"follow" | "error" | "manual"nullform-ref
<form> to intercept. The form's action / method / enctype take priority over api-url / api-method below. Must be a descendant to be heard directly — point elsewhere and invoke the --submit command instead.
formRef
string
<CSS Selector>":scope form"form-ref
<form> to source the request from — its action (URL), method, enctype (Content-Type), and field values (as the JSON payload) all take priority over the matching attributes below. Omit to build the request entirely from attributes / custom doFetch() args.
formRef
string
<CSS Selector>nullhas-body
GET / HEAD). Already implied for POST / PUT / PATCH.
hasBody
boolean
falseheader-accept
Accept request header.
headerAccept
string
"application/json"header-cache-control
Cache-Control request header. Unset by default (browser default caching applies).
headerCacheControl
string
nullheader-content-type
Content-Type request header. Dropped entirely when the request has no body.
headerContentType
string
"application/json"is-error
AbortError). Fires with the error event.
isError
boolean
falseis-loading
isLoading
boolean
falseis-success
is-loading and is-error.
isSuccess
boolean
falseProvision (1)
Thisprovision property lives on the DOM node.
Read / watch it with Quark’s prop("provision"), or listen
for the neutron-provision event from app JS.
provision
{ status, statusText, ok, headers, url, redirected, bodyUsed, type, body }. Failure shape is either that same response shape (server responded with an error status) or { message, stack } (request never completed). Not reflected as an attribute.
provision
FetchResponse
Events (6)
e.preventDefault() is not
synchronously called on the event.
Type
super-form-error
event.detail is the error payload (see provision). Not dispatched for aborted requests.
Type
FetchableErrorEvent
super-form-loading
Type
FetchableLoadingEvent
super-form-submit
submit or the --submit command). Built by getFetchArgs(). Cancelable; default action calls doFetch().
Type
SuperFormSubmitEvent
doFetch([url, requestInit]) with the event's detail.super-form-success
event.detail is the parsed response (see provision).
Type
FetchableSuccessEvent
submitSuperFormNativeSubmitEvent
<form> matched by form-ref (or any descendant <form>); prevented, then converted into super-form-submit.
command event (HTML Command API): from a
<button command commandfor>, an <event-handler
command-name>, or a CommandEvent.
--submit<button command="--submit" commandfor="…">) — the only option when form-ref points to a form that isn't a descendant, since this element can't hear its submit event directly.
Recognized Elements (0)
Child or descendant elements are recognized by super-form and relevant to its functionality.Styles (0)
all: revert-layer.
Valence.css ships this as .unstyled and .unstyled-all for the entire tree.
@custom-selector synonyms so custom elements can share
semantic styles. Element aliases match the host tag / .tag-* class; state
aliases match attributes (nested under the element alias).
Release notes (1)
0.1.1
- Ship only dist (and declared extras) in the npm tarball; drop build logs, tests and sources
Release notes
e.preventDefault() is not
synchronously called on the event.
all: revert-layer.
Valence.css ships this as .unstyled and .unstyled-all for the entire tree.
Examples
Comprehensive
This example shows loading state, error state, rendering, and triggering from outside the form.