Forms are used to collect user input, which can then be sent to a server for processing.
All form input components use the formdata event , which is available in all modern browsers. This means, when a form is submitted, Ods form controls will automatically append their values to the FormData object that’s used to submit the form.
Serialization is just a fancy word for collecting form data. If you’re relying on standard form submissions, e.g. <form action="..."> , you can probably skip this section. However, most modern apps use the Fetch API or another library to submit forms using JavaScript. The FormData interface offers a standard way to serialize forms in the browser. You can create a FormData object from any <form> element like this.
Form Data:
<div ods-layout="block gap:lg align:stretch"> <form id="form-data-simple" class="inline-validation"> <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 name="firstName" label="First Name" required value="John"></ods-input> </div>
<div ods-layout="inline gap:md stretch"> <ods-input name="lastName" label="Last Name" required value="Smith"></ods-input> </div>
<div ods-layout="inline gap:md"> <ods-button type="submit" variant="primary">Submit</ods-button> <ods-button type="reset" variant="secondary">Reset</ods-button> </div> </div> </fieldset> </form>
<p id="form-data-simple-output" class="text-base">Form Data:</p></div>
<script type="module"> const form = document.querySelector('#form-data-simple'); const formDataOutput = document.querySelector('#form-data-simple-output');
// Wait for controls to be defined before attaching form listeners await Promise.all([ customElements.whenDefined('ods-button'), customElements.whenDefined('ods-input') ]).then(() => { form.addEventListener('submit', event => { event.preventDefault();
const formData = new FormData(form);
formDataOutput.innerHTML = `Form Data: ${JSON.stringify(Object.fromEntries(formData))}`; }); }); </script>import { useState } from 'react';import { OdsButton } from '@ods/components/react.button';import { OdsInput } from '@ods/components/react.input';
const Example = () => { const [formData, setFormData] = useState('');
const handleSubmit = (event:any) => { event.preventDefault();
const formData = new FormData(event.currentTarget);
setFormData(JSON.stringify(Object.fromEntries(formData))) };
return ( <div ods-layout="block gap:lg align:stretch"> <form onSubmit={handleSubmit} className="inline-validation"> <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 value="John"></OdsInput> </div>
<div ods-layout="inline gap:md stretch"> <OdsInput name="lastName" label="Last Name" required value="Smith"></OdsInput> </div>
<div ods-layout="inline gap:md"> <OdsButton type="submit" variant="primary">Submit</OdsButton> <OdsButton type="reset" variant="secondary">Reset</OdsButton> </div> </div> </fieldset> </form>
<p className="text-base">Form Data: {formData}</p> </div> )}
export default Example;The following form includes all the various input you may use in a form.
Form Data:
<div ods-layout="block gap:lg align:stretch"> <form id="form-data-complex" 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" name="email" label="Email" placeholder="user@example.com" required value="test@user.com"></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." value="Test123!"></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 name="firstName" label="First Name" required value="Test"></ods-input> <ods-input name="middleName" label="Middle Name"></ods-input> <ods-input name="lastName" label="Last Name" required value="User"></ods-input> </div>
<div ods-layout="inline gap:md stretch"> <ods-input type="number" name="age" label="Age" required value="21"></ods-input> </div>
<div ods-layout="inline gap:md stretch"> <ods-input type="date" name="date" label="Date" required help-text="help text here" error-text="error text here" value="2024-10-04"></ods-input> </div>
<div ods-layout="inline gap:md stretch"> <ods-select name="select" label="Select one" required clearable value="option-1"> <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 name="'checkbox" required checked>Check me before submitting</ods-checkbox>
<ods-radio-group name="radio-group" required label="Select an Option" value="1"> <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-textarea name="comments" label="Comments" required help-text="Please add any additional info that may be helpful." value="Test comment"></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>
<p id="form-complex-data-output" class="text-base">Form Data:</p></div>
<script type="module"> const form = document.querySelector('#form-data-complex'); const formDataOutput = document.querySelector('#form-complex-data-output');
// Wait for controls to be defined before attaching form listeners await Promise.all([ customElements.whenDefined('ods-button'), customElements.whenDefined('ods-input'), customElements.whenDefined('ods-select'), customElements.whenDefined('ods-checkbox'), customElements.whenDefined('ods-radio-group'), customElements.whenDefined('ods-textarea') ]).then(() => { form.addEventListener('submit', event => { event.preventDefault();
const formData = new FormData(form);
console.log('formData: ', formData)
formDataOutput.innerHTML = `Form Data: ${JSON.stringify(Object.fromEntries(formData))}`; }); });</script>import { useState } from 'react';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 = () => { const [formData, setFormData] = useState('');
const handleSubmit = (event:any) => { event.preventDefault();
const formData = new FormData(event.currentTarget);
setFormData(JSON.stringify(Object.fromEntries(formData))) };
return ( <div ods-layout="block gap:lg align:stretch"> <form onSubmit={handleSubmit} className="inline-validation"> <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 value="Test"></OdsInput> <OdsInput name="middleName" label="Middle Name"></OdsInput> <OdsInput name="lastName" label="Last Name" required value="User"></OdsInput> </div>
<div ods-layout="inline gap:md"> <OdsInput type="number" name="age" label="Age" required value="21"></OdsInput> </div>
<div ods-layout="inline gap:md stretch"> <OdsInput type="date" name="date" label="Date" required help-text="help text here" error-text="error text here" value="2024-10-04"></OdsInput> </div>
<div ods-layout="inline gap:md stretch"> <OdsInput type="email" name="email" label="Email" placeholder="user@example.com" required value="test@user.com"></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." value="Test123!"></OdsInput> </div>
<div ods-layout="inline gap:md stretch"> <OdsSelect name="select" label="Select one" required clearable value="option-1"> <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" value="1"> <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"> <OdsTextarea name="comments" label="Comments" required help-text="Please add any additional info that may be helpful." value="Test comment"></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>
<p className='text-base'>Form Data: {formData}</p> </div> )}
export default Example;