Skip to content
ONIWC
iwc 0.1.0

form element

Collects input and submits it as JSON to a POST/PUT/PATCH/DELETE API, showing the server's validation errors next to each field.

Renders

<form> with labelled controls, an error area and a submit button

Required

inputs (or elements) and submit.api.

Native apps

Web, and server-driven native apps

Syntax

form element
{ "type": "form" }

An element lives in a screen's sections, another element's elements, a layout slot or a component root.

Properties

PropertyTypeDescription
inputsarray of input
submitobject
  • api: string — the api file the form posts to
  • className: string — CSS classes for the submit button; they replace its variant styling
  • include: array of string
  • label: string
  • streamInto: string — a streaming api ("stream": true): the id of the element the reply's text is written into as it arrives
  • success: object
elementsarray of element

Plus the properties every element accepts: id, className, style, responsive, states, animation, visible, ariaLabel, attributes and more.

Events & actions

On 2xx: submit.success (message, reset, navigate, redirect, mutation, reload). On 422: field errors under each input. Sign-in forms return the visitor to ?next=.

Example

form example
{
  "type": "form",
  "inputs": [
    {
      "name": "email",
      "type": "email",
      "label": "Email",
      "required": true,
      "autocomplete": "email"
    },
    {
      "name": "topic",
      "type": "select",
      "label": "Topic",
      "options": ["Order", "Returns", "Other"]
    },
    {
      "name": "message",
      "type": "textarea",
      "label": "Message",
      "required": true,
      "hint": "We reply within a day."
    }
  ],
  "submit": {
    "api": "contact.api.iwc",
    "label": "Send",
    "success": { "message": "Thanks — we'll be in touch.", "reset": true }
  }
}

required on an input only marks the field in the browser; the API's request contract enforces it. Every input type is documented on the form inputs page.

Expected output

The HTML IWC rendered for the example above (inside the page's content wrapper). Class names such as i807b63fc are generated per element for its scoped CSS.

Rendered HTML
<div class="iwc-page ipage" id="iwc-content">
  <form class="iwc-form i31a182c2" method="post" action="/api/contact" data-iwc-form data-method="POST" novalidate data-success="{&#34;message&#34;:&#34;Thanks — we&#39;ll be in touch.&#34;,&#34;reset&#34;:true}">
    <div class="iwc-field" data-field="email">
      <label for="f-email">Email</label>
      <input type="email" id="f-email" name="email" required autocomplete="email">
      <span class="iwc-field-error" data-error-for="email"></span>
    </div>
    <div class="iwc-field" data-field="topic">
      <label for="f-topic">Topic</label>
      <select id="f-topic" name="topic">
        <option value="Order">Order</option><option value="Returns">Returns</option><option value="Other">Other</option>
      </select>
      <span class="iwc-field-error" data-error-for="topic"></span>
    </div>
    <div class="iwc-field" data-field="message">
      <label for="f-message">Message</label>
      <textarea id="f-message" name="message" required aria-describedby="f-message-hint" rows="4">
      </textarea>
      <small class="iwc-field-hint" id="f-message-hint">We reply within a day.</small><span class="iwc-field-error" data-error-for="message"></span>
    </div>
    <div class="iwc-form-message" role="status" aria-live="polite">
    </div>
    <button type="submit" class="iwc-button iwc-button-primary">
      Send
    </button>
  </form>
</div>

Data, conditions & styling

  • Conditional rendering: "visible": {"auth": "signed-in"}, {"roles": ["admin"]} or an expression such as "=product.stock > 0". Decided on the server: hidden elements are never sent.
  • Data binding: bind takes text from data (name, user.name, props.title, params.slug, state.cart.count); binds binds attributes. Containers become data-driven with data + item. See data binding.
  • Styling: className for your stylesheets, style for CSS in JSON, states for hover/focus/active, animation for entrance motion. See the style property reference.
  • Responsive behaviour: responsive applies CSS at or below a breakpoint ({"mobile": {"padding": "12px"}}); grids also take responsiveColumns.