Before submitting data to the server, it is important to ensure all required form controls are filled out, in the correct format. This is called form validation, and helps ensure data submitted matches the requirements set forth in the various form controls.
Client-side validation can be enabled through the browser’s constraint validation API for form controls. You can activate it using attributes such as required, pattern, minlength, maxlength, etc.
If you don’t want to use client-side validation, you can suppress this behavior by adding novalidate to the surrounding <form > element.
To make a field required, use the required attribute. Required fields will automatically receive a blue circle after their labels. The form will not be submitted if the required field is incomplete.
<form class="inline-validation"> <div ods-layout="block gap:lg"> <div ods-layout="inline gap:md stretch"> <ods-input label="Text" required placeholder='placeholder text'></ods-input> </div>
<div ods-layout="inline gap:md"> <ods-button type="submit" variant="primary">Submit</ods-button> <ods-button variant="secondary" type="reset">Reset</ods-button> </div> </div></form>import { OdsButton } from '@ods/components/react.button';import { OdsInput } from '@ods/components/react.input';
const Example = () => { return ( <form className="inline-validation"> <div ods-layout="block gap:lg"> <div ods-layout="inline gap:md stretch"> <OdsInput label="Text" required placeholder='placeholder text'></OdsInput> </div>
<div ods-layout="inline gap:md"> <OdsButton type="submit" variant="primary">Submit</OdsButton> <OdsButton variant="secondary" type="reset">Reset</OdsButton> </div> </div> </form> )}
export default Example; To restrict a value to a specific pattern, use the pattern attribute. This example only allows the letters A-Z, so the form will not submit if a number or symbol is entered. This only works with <ods-input> elements.
<form class="inline-validation"> <div ods-layout="block gap:lg"> <div ods-layout="inline gap:md stretch"> <ods-input name="letters" label="Letters Only" required pattern="[A-Za-z]+"></ods-input> </div>
<div ods-layout="inline gap:md"> <ods-button type="submit" variant="primary">Submit</ods-button> <ods-button variant="secondary" type="reset">Reset</ods-button> </div> </div></form>import { OdsButton } from '@ods/components/react.button';import { OdsInput } from '@ods/components/react.input';
const Example = () => { return ( <form className="inline-validation"> <div ods-layout="block gap:lg"> <div ods-layout="inline gap:md stretch"> <OdsInput name="letters" label="Letters Only" required pattern="[A-Za-z]+"></OdsInput> </div>
<div ods-layout="inline gap:md"> <OdsButton type="submit" variant="primary">Submit</OdsButton> <OdsButton variant="secondary" type="reset">Reset</OdsButton> </div> </div> </form> )}
export default Example;Some input types will automatically trigger constraints, such as email and url.
<form class="inline-validation"> <div ods-layout="block gap:lg"> <div ods-layout="inline gap:md stretch"> <ods-input type="email" label="Email" placeholder="test@example.com" required></ods-input> </div>
<div ods-layout="inline gap:md stretch"> <ods-input type="url" label="URL" placeholder="https://example.com/" required></ods-input> </div>
<div ods-layout="inline gap:md"> <ods-button type="submit" variant="primary">Submit</ods-button> <ods-button variant="secondary" type="reset">Reset</ods-button> </div> </div></form>import { OdsButton } from '@ods/components/react.button';import { OdsInput } from '@ods/components/react.input';
const Example = () => { return ( <form className="inline-validation"> <div ods-layout="block gap:lg"> <div ods-layout="inline gap:md stretch"> <OdsInput type="email" label="Email" placeholder="test@example.com" required></OdsInput> </div>
<div ods-layout="inline gap:md stretch"> <OdsInput type="url" label="URL" placeholder="https://example.com/" required></OdsInput> </div>
<div ods-layout="inline gap:md"> <OdsButton type="submit" variant="primary">Submit</OdsButton> <OdsButton variant="secondary" type="reset">Reset</OdsButton> </div> </div> </form> )}
export default Example;When a form input is invalid and the user has interacted with it, it will replace the help text field with the appropriate validation message . This message describes the validation constraints that the control does not satisfy.
<form class="inline-validation"> <div ods-layout="block gap:lg"> <div ods-layout="inline gap:md stretch"> <ods-input label="Default Error Message" required help-text="Help text goes here"></ods-input> </div>
<div ods-layout="inline gap:md"> <ods-button type="submit" variant="primary">Submit</ods-button> <ods-button variant="secondary" type="reset">Reset</ods-button> </div> </div></form>import { OdsButton } from '@ods/components/react.button';import { OdsInput } from '@ods/components/react.input';
const Example = () => { return ( <form className="inline-validation"> <div ods-layout="block gap:lg"> <div ods-layout="inline gap:md stretch"> <OdsInput label="Default Error Message" required help-text="Help text goes here"></OdsInput> </div>
<div ods-layout="inline gap:md"> <OdsButton type="submit" variant="primary">Submit</OdsButton> <OdsButton variant="secondary" type="reset">Reset</OdsButton> </div> </div> </form> )}
export default Example; If you don’t want to use the default validation message, you can define your own by passing in a custom error message via the error-text attribute.
<form class="inline-validation"> <div ods-layout="block gap:lg"> <div ods-layout="inline gap:md stretch"> <ods-input label="Custom Error Message" required help-text="Help text goes here" error-text="Custom error text"></ods-input> </div>
<div ods-layout="inline gap:md"> <ods-button type="submit" variant="primary">Submit</ods-button> <ods-button variant="secondary" type="reset">Reset</ods-button> </div> </div></form>import { OdsButton } from '@ods/components/react.button';import { OdsInput } from '@ods/components/react.input';
const Example = () => { return ( <form className="inline-validation"> <div ods-layout="block gap:lg"> <div ods-layout="inline gap:md stretch"> <OdsInput label="Custom Error Message" required help-text="Help text goes here" error-text="Custom error text"></OdsInput> </div>
<div ods-layout="inline gap:md"> <OdsButton type="submit" variant="primary">Submit</OdsButton> <OdsButton variant="secondary" type="reset">Reset</OdsButton> </div> </div> </form> )}
export default Example;The following example showcases all the various form controls that could be used in a form and their corresponding error states.
<form class="inline-validation" ods-layout="block gap:48 align:inline-stretch"> <fieldset> <legend ods-layout="mb:16" ods-text="headline semibold size:lg">Login Information</legend> <div ods-layout="block gap:lg"> <div ods-layout="inline gap:md stretch"> <ods-input type="email" label="Email" placeholder="user@example.com" required></ods-input> </div>
<div ods-layout="inline gap:md stretch"> <ods-input type="password" label="Password" required pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).{8,16}$" error-text="Must be at least 8 characters long and contain one uppercase letter, one number and one special character."></ods-input> </div> </div> </fieldset> <fieldset> <legend ods-layout="mb:16" ods-text="headline semibold size:lg">Patient Information</legend> <div ods-layout="block gap:lg"> <div ods-layout="inline gap:md stretch"> <ods-input label="First Name" required></ods-input> <ods-input label="Middle Initial"></ods-input> <ods-input label="Last Name" required></ods-input> </div>
<div ods-layout="inline gap:md stretch"> <ods-input type="number" label="Age" required></ods-input> </div>
<div ods-layout="inline gap:md stretch"> <ods-input type="date" label="Date" required></ods-input> </div>
<div ods-layout="inline gap:md stretch"> <ods-select label="Select one" required clearable> <ods-option value="option-1">Option 1</ods-option> <ods-option value="option-2">Option 2</ods-option> <ods-option value="option-3">Option 3</ods-option> </ods-select> </div>
<ods-checkbox required>Check me before submitting</ods-checkbox>
<ods-radio-group required label="Select an Option"> <ods-radio value="1">Option 1</ods-radio> <ods-radio value="2">Option 2</ods-radio> <ods-radio value="3">Option 3</ods-radio> </ods-radio-group>
<div ods-layout="inline gap:md stretch"> <ods-input label="Short Comment" required help-text="Please add any additional info that may be helpful." minlength="5" maxlength="15" show-count-text></ods-input> </div>
<div ods-layout="inline gap:md stretch"> <ods-textarea label="Long comment" required help-text="Please add any additional info that may be helpful." required minlength="5" maxlength="100" show-count-text></ods-textarea> </div>
<div ods-layout="inline gap:md"> <ods-button type="submit" variant="primary">Submit</ods-button> <ods-button variant="secondary" type="reset">Reset</ods-button> </div> </div> </fieldset></form>import { OdsButton } from '@ods/components/react.button';import { OdsInput } from '@ods/components/react.input';import { OdsRadioGroup } from '@ods/components/react.radio-group';import { OdsRadio } from '@ods/components/react.radio';import { OdsCheckbox } from '@ods/components/react.checkbox';import { OdsTextarea } from '@ods/components/react.textarea';import { OdsSelect } from '@ods/components/react.select';import { OdsOption } from '@ods/components/react.option';
const Example = () => { return ( <form ods-layout="block gap:48 align:inline-stretch"> <fieldset> <legend ods-layout="mb:16" ods-text="headline semibold size:lg">Login Information</legend> <div ods-layout="block gap:lg"> <div ods-layout="inline gap:md stretch"> <OdsInput type="email" name="email" label="Email" placeholder="user@example.com" required></OdsInput> </div>
<div ods-layout="inline gap:md stretch"> <OdsInput type="password" name="password" label="Password" required pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).{8,16}$" error-text="Must be at least 8 characters long and contain one uppercase letter, one number and one special character."></OdsInput> </div> </div> </fieldset> <fieldset> <legend ods-layout="mb:16" ods-text="headline semibold size:lg">Patient Information</legend> <div ods-layout="block gap:lg"> <div ods-layout="inline gap:md stretch"> <OdsInput name="firstName" label="First Name" required></OdsInput> <OdsInput name="middleName" label="Middle Name"></OdsInput> <OdsInput name="lastName" label="Last Name" required></OdsInput> </div>
<div ods-layout="inline gap:md stretch"> <OdsInput type="number" name="age" label="Age" required></OdsInput> </div>
<div ods-layout="inline gap:md stretch"> <OdsInput type="date" name="date" label="Date" required></OdsInput> </div>
<div ods-layout="inline gap:md stretch"> <OdsSelect name="select" label="Select one" required clearable> <OdsOption value="option-1">Option 1</OdsOption> <OdsOption value="option-2">Option 2</OdsOption> <OdsOption value="option-3">Option 3</OdsOption> </OdsSelect> </div>
<OdsCheckbox name="'checkbox" required checked>Check me before submitting</OdsCheckbox>
<OdsRadioGroup name="radio-group" required label="Select an Option"> <OdsRadio value="1">Option 1</OdsRadio> <OdsRadio value="2">Option 2</OdsRadio> <OdsRadio value="3">Option 3</OdsRadio> </OdsRadioGroup>
<div ods-layout="inline gap:md stretch"> <OdsInput label="Short Comment" required minlength={5} maxlength={15} show-count-text></OdsInput> </div>
<div ods-layout="inline gap:md stretch"> <OdsTextarea name="comments" label="Comments" help-text="Please add any additional info that may be helpful." required minlength={5} maxlength={100} show-count-text></OdsTextarea> </div>
<div ods-layout="inline gap:md"> <OdsButton type="submit" variant="primary">Submit</OdsButton> <OdsButton variant="secondary" type="reset">Reset</OdsButton> </div> </div> </fieldset> </form> )}
export default Example;