Getting started with webbloqs Forms
Installation
To install the webbloqs package, run the following command:
pnpm add @webbloqs/react
Usage
To build a form with webbloqs, import Form
and some form elements from the @webbloqs/react
package.
The components from @webbloqs/react
are Web Components, and they rely on the ElementInternals interface to associate form elements with their form.
For this reason you must set a matching formId
property on the Form
and a matching form
property on each contained form element.
import { CheckboxField, DropdownField, Form, Layout, RadioField, TextField } from '@webbloqs/react';
const FORM_ID = "basic-form";
<Form formId={FORM_ID}>
<RadioField
form={FORM_ID}
name="salutation"
options={[
{ label: "Mr", value: "mr", selected: true },
{ label: "Mrs", value: "mrs" },
]}
/>
<Layout distribution="1|1">
<TextField form={FORM_ID} name="firstname" label="First Name" required/>
<TextField form={FORM_ID} name="lastname" label="Last Name" required/>
</Layout>
<DropdownField
form={FORM_ID}
name="country"
label="Country"
options={[
{ label: "Switzerland", value: "ch", checked: true },
{ label: "Germany", value: "de" },
{ label: "France", value: "fr" },
]}
/>
<CheckboxField
form={FORM_ID}
name="newsletter"
options={[{ label: "I want to receive the newsletter", value: "yes" }]}
/>
</Form>;
See this form in action in the webbloqs catalog, and Form Elements for the full list of elements.
Form
comes with a predefined submit button, its label can be customized as follows:
<Form submitLabel="Create Account">
{/* form elements as above */}
</Form>
Learn about additional options to customize the form's appearance and behaviour in the TODO advanced usage section.
Data Handling and Submission
A Form
automatically gathers all associated form values and provides them to the handleSubmit
callback as a FormData
object.
You can determine that form submission was successful if the promise resolves, in that case the content of the result
slot will be displayed.
The standard HTML validation can be used to validate user input.
To prevent submission you can simply return a rejected Promise in your handleSubmit
callback, in that case you may display a custom error message to the user by specifying the content of the error
slot.
<Form handleSubmit={(event: InputEvent, formData: FormData): Promise<void> => {
console.log([...formData.entries()]);
return Promise.resolve();
}}>
{/* form elements as above */}
<div slot="result">Your account has been created successfully.</div>
<div slot="error">An error occurred, please try again later.</div>
</Form>
Advanced Form Concepts
Multistep Forms
Multistep forms are a common pattern in web applications, allowing users to fill out complex forms in a more manageable way, the webbloqs FormStep
component can be used in conjunction with Form
to create such a multistep form.
Each FormStep
must be identified by a unique id
for proper form data collection and can have an optional title
. The form will then automatically show a configurable "next" and "previous" button to navigate between the steps.
import { CheckboxField, Form, FormStep, Layout, TextField } from '@webbloqs/react';
const FORM_ID = "conditional-fields";
<Form formId={FORM_ID}>
<FormStep id="user-info" title="User Info">
<Layout distribution="1|1">
<TextField form={FORM_ID} name="firstname" label="First Name" required />
<TextField form={FORM_ID} name="lastname" label="Last Name" required />
</Layout>
</FormStep>
<FormStep id="address-data" title="Address Data">
<TextField form={FORM_ID} name="street" label="Street" required />
<Layout distribution="1|1">
<TextField form={FORM_ID} name="postalcode" label="Postal Code" required />
<TextField form={FORM_ID} name="city" label="City" required />
</Layout>
</FormStep>
</Form>
Conditional Fields
With the condition
property on FieldGroup
webbloqs provides a mechanism to set field state based on the value of other fields.
Both the condition source and the FieldGroup
itself must be part of the same form, wired up via their form
property.
Property | Type | Function |
---|---|---|
conditionSourceName | string | Declare the field name for which this condition applies. |
predicate | function | Provide a function that is called whenever the condition source value is updated. |
getTarget | function | Optional method to define a different target for the condition than the FieldGroup. |
import { CheckboxField, FieldGroup, Form, TextField } from '@webbloqs/react';
const FORM_ID = "conditional-fields";
<Form formId={FORM_ID}>
<CheckboxField
form={FORM_ID}
name="show-section"
options={[
{
label: "Show section",
value: "on",
},
]}
/>
<FieldGroup
form={FORM_ID}
condition={{
conditionSourceName: "show-section",
predicate: (value, { setVisible }) => setVisible(value === "on"),
}}>
<TextField form={FORM_ID} name="firstname" label="First Name" required />
<TextField form={FORM_ID} name="lastname" label="Last Name" required />
</FieldGroup>
</Form>
Custom Field Validation
With the onValidate
property on form elements you can easily add custom validation logic to your form fields.
This property accepts a function that receives the current value of the field and returns either a string with your custom error message if the value is invalid or null
otherwise.
Note that standard validations like
required
will still apply after your custom validation.
import { Form, TextField } from '@webbloqs/react';
const FORM_ID = "custom-validation";
<Form formId={FORM_ID}>
<TextField
form={FORM_ID}
name="phone"
label="Phone"
onValidate={(value: string) => {
return /\d{10}/.test(value) ? null : "No valid swiss phone number.";
}}
required
/>
</Form>