While Elastic is most known for our open-source search tools, did you know we also have an open-source design library that anyone can use for creating the user interface inside of your apps and websites? You can not only handle your data with Elastic, but you can also display and interact with the data with Elastic too!
It’s all thanks to our design library called EUI (Elastic User Interface). You might recognize some of the components (no pun intended) from Kibana. For today’s post, I want to share one of my favorite EUI Component - The Form - and how you can use it in your app.
Set up EUI
Getting started with EUI in your React app is simple. For the most part, you just need to add @elastic/eui
as a dependency in your project and import the CSS files. Then you’re ready to start using the components!
Out of the Box Form
Just about every app needs to collect input from a user and EUI provides a lot of options for doing just that. The styling comes out of the box but allows for customization. (As a bonus, you can apply classNames
to every EUI component to apply your own custom styles.)
We use the form component in our customer support portal for users to create a new support case.
As you can see, you can use just about anything as an input type! We have some really advanced dropdowns here, a file picker, a text input, and even a markdown editor!
Here’s an example of how we format a field for adding contacts to a case:
<EuiFormRow
fullWidth // this defines the width
label={
<EuiI18n
token="newCase.informed"
default="Who else should we keep informed? (optional)"
/>
} // label for the row, with options for localizing text through our i18n utility
>
<EuiI18n
token="newCase.informedPlaceholder"
default="Select contacts"
> // default text over the box
{(informedPlaceholder: string) => (
<EuiComboBox // dropdown input type
fullWidth
isClearable={true} // customization option allowing you to define the ability to remove all the selections
isLoading={
this.props.contacts.loading ? true : undefined
} // define a loading state
onChange={this.handleContactSelect} // what it sounds like :)
options={this.state.contactOptions} // an array containing all the dropdown values
placeholder={informedPlaceholder} // default text
selectedOptions={this.state.contactsSelected} // which values are selected
/>
)}
</EuiI18n>
</EuiFormRow>
You can read more about these props in the EUI Docs.
Incorporating Validation
If you want to ensure only the right data comes through the field, you'll be able to easily set up form validation and error handling with EUI.
You'll need to add two props to a form row to set it, and then you'll need to create an onChange
event for the field and/or an onSubmit
event for the form to check the criteria of the values.
- Define
isInvalid
. You'll need to add a prop to your field that accepts a boolean for showing if the field is valid or not. This will change the color of the field's box tored
so that a user can visibly see the field needs edits. This is the field we will set in theonSubmit
function in a few steps.
isInvalid={this.state.formErrors.statusEmpty}
- Pass an array of messages to show
error
. This could be just one error (like "cannot be blank"), or if you have multiple types of errors that can occur, you can pass each of those in there with the criteria.)
error={[
// we're passing two errors - one that checks if the field is empty
// and another to check if it's too long
this.state.formErrors.bodyTooLong && (
<EuiI18n
token="newCase.lengthErrorMessage"
default="Must be less than {maxLength} characters."
values={{
maxLength: MAX_BODY_LENGTH,
}}
/>
),
this.state.formErrors.bodyEmpty && (
<EuiI18n
token="newCase.bodyEmptyErrorMessage"
default="The description cannot be empty."
/>
),
]}
- Create a handler function to check your criteria on form submission and update your isInvalid/error fields.
if (
!body ||
!subject
) {
this.setState((prevState) => {
return {
formErrors: {
...prevState.formErrors,
bodyEmpty: !body,
subjectEmpty: !subject,
},
};
});
And voila! Now you have error handling!
Note - you can also create an onChange
or onBlur
event on those inputs to check before the form is submitted.
I've only scratched the surface here. To learn more, check out the EUI Forms docs and see all the different ways you can customize them and use them!