Skip to main content

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.

PropertyTypeFunction
conditionSourceNamestringDeclare the field name for which this condition applies.
predicatefunctionProvide a function that is called whenever the condition source value is updated.
getTargetfunctionOptional 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>