Skip to main content

Form Building


Note:
We would appreciate any feedback on our tutorial guide. If you are stuck at any time, make sure to contact the Abyss Admiral assigned to your team. If they cannot help, send a help request on our Contact Page.


Before starting, be sure to complete the Create Abyss App tutorial.

Step 1: Create a Form Page

In Visual Studio Code, open my-new-app project. From here, navigate into products/web/src/routes, and create a new folder, name "FormPage". Within this new folder, we'll be creating two new files, named "index.ts" and "FormPage.tsx".

Connect your page to the router in products/web/src/routes/Routes.tsx by including a new Route shown below:

<Router.Route path="/form-page" element={<FormPage />} />

You may reference the Page Routing tutorial for more information on creating pages.

Step 2: Building A Form

Within FormPage.tsx we'll be adding the FormProvider and TextInput components to create a sample form. At the top of your file, copy and paste the following import statements:

import React from 'react';
import { useForm } from '@uhg-abyss/web/hooks/useForm';
import { FormProvider } from '@uhg-abyss/web/ui/FormProvider';
import { TextInput } from '@uhg-abyss/web/ui/TextInput';

A form can consist of many types of input components. In this form, we are using TextInput to populate the user's first name, middle name, and last name. Make sure all inputs are children of the FormProvider component.

Also be sure to provide default values for each field to the defaultValues prop within useForm. This ensures the form will properly reset to these default values whenever calling the reset method.

We can also include a SelectInput component as another alternative to collecting user input. Import your SelectInput component, and then add the following code after the last TextInput component:

<SelectInput
label="Favorite Fruit"
validators={{ required: true }}
isClearable
isSearchable
model="favoriteFruit"
options={[
{ value: 'honeycrisp-apple', label: 'Honeycrisp Apple' },
{ value: 'pineapple', label: 'Pineapple' },
{ value: 'mango', label: 'Mango' },
{ value: 'banana', label: 'Banana' },
{ value: 'raspberry', label: 'Raspberry' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'blueberry', label: 'Blueberry' },
]}
/>

Lastly, we will create buttons in order to submit and clear the form inputs. The Layout component will be utilized in order to format the page. Import the Button and Layout components, and then after the last SelectInput that you added above, within the body of FormProvider, insert the following code:

<Layout.Space />
<Layout.Group alignLayout="right">
<Button variant="outline" onClick={handleClear}>
Clear Form
</Button>
<Button type="submit">Submit Form</Button>
</Layout.Group>

Let's add handlers for our submit and clear functions. Below the useForm() hook, add the two functions below for handleSubmit and handleClear.

const emptyDefaultValues = {
firstName: '',
lastName: '',
middleName: '',
favoriteFruit: '',
};
const form = useForm({
defaultValues: emptyDefaultValues,
});
const handleSubmit = (data) => {
console.log('Form Data', data);
alert('Submitted!');
};
const handleClear = () => {
form.reset();
};

Finally, attach the handleSubmit function by adding an onSubmit prop to your FormProvider.

<FormProvider state={form} onSubmit={handleSubmit}>

Step 3: Testing your Form

At the end of creating a form & submitting the data, your code in FormPage.tsx should look like this:

import React from 'react';
import { useForm } from '@uhg-abyss/web/hooks/useForm';
import { FormProvider } from '@uhg-abyss/web/ui/FormProvider';
import { TextInput } from '@uhg-abyss/web/ui/TextInput';
import { SelectInput } from '@uhg-abyss/web/ui/SelectInput';
import { Button } from '@uhg-abyss/web/ui/Button';
import { Layout } from '@uhg-abyss/web/ui/Layout';
export const FormPage = () => {
const emptyDefaultValues = {
firstName: '',
lastName: '',
middleName: '',
favoriteFruit: '',
};
const form = useForm({
defaultValues: emptyDefaultValues,
});
const handleSubmit = (data) => {
console.log('Form Data', data);
alert('Submitted!');
};
const handleClear = () => {
form.reset();
};
return (
<FormProvider state={form} onSubmit={handleSubmit}>
<TextInput
label="First Name"
model="firstName"
isClearable
validators={{ required: true }}
/>
<TextInput label="Middle Name" model="middleName" isClearable />
<TextInput
label="Last Name"
model="lastName"
isClearable
validators={{ required: true }}
/>
<SelectInput
label="Favorite Fruit"
validators={{ required: true }}
isClearable
isSearchable
model="favoriteFruit"
options={[
{ value: 'honeycrisp-apple', label: 'Honeycrisp Apple' },
{ value: 'pineapple', label: 'Pineapple' },
{ value: 'mango', label: 'Mango' },
{ value: 'banana', label: 'Banana' },
{ value: 'raspberry', label: 'Raspberry' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'blueberry', label: 'Blueberry' },
]}
/>
<Layout.Space />
<Layout.Group alignLayout="right">
<Button variant="outline" onClick={handleClear}>
Clear Form
</Button>
<Button type="submit">Submit Form</Button>
</Layout.Group>
</FormProvider>
);
};

Great job, you have successfully built a form!

Table of Contents