Skip to main content

Autosave Select, Radio, and Checkbox

Form Guardian automatically handles select, radio, and checkbox fields. This guide shows you best practices for these input types.

Select Dropdowns

Select fields work automatically with Form Guardian:

import { useFormAutosave } from '@form-guardian/react';

function SelectForm() {
const { formRef, clearDraft } = useFormAutosave('select-form', {
autoRestore: true,
});

return (
<form ref={formRef}>
<select name="country">
<option value="">Select country</option>
<option value="us">United States</option>
<option value="uk">United Kingdom</option>
<option value="ca">Canada</option>
</select>

<select name="state" multiple>
<option value="ny">New York</option>
<option value="ca">California</option>
<option value="tx">Texas</option>
</select>

<button type="submit">Submit</button>
</form>
);
}

Radio Buttons

Radio buttons are automatically tracked:

function RadioForm() {
const { formRef, clearDraft } = useFormAutosave('radio-form', {
autoRestore: true,
});

return (
<form ref={formRef}>
<fieldset>
<legend>Choose a plan</legend>
<label>
<input type="radio" name="plan" value="basic" />
Basic
</label>
<label>
<input type="radio" name="plan" value="pro" />
Pro
</label>
<label>
<input type="radio" name="plan" value="enterprise" />
Enterprise
</label>
</fieldset>

<button type="submit">Submit</button>
</form>
);
}

Checkboxes

Single and multiple checkboxes work automatically:

function CheckboxForm() {
const { formRef, clearDraft } = useFormAutosave('checkbox-form', {
autoRestore: true,
});

return (
<form ref={formRef}>
{/* Single checkbox */}
<label>
<input type="checkbox" name="newsletter" />
Subscribe to newsletter
</label>

{/* Multiple checkboxes with same name */}
<fieldset>
<legend>Interests</legend>
<label>
<input type="checkbox" name="interests" value="tech" />
Technology
</label>
<label>
<input type="checkbox" name="interests" value="sports" />
Sports
</label>
<label>
<input type="checkbox" name="interests" value="music" />
Music
</label>
</fieldset>

<button type="submit">Submit</button>
</form>
);
}

With React Hook Form

React Hook Form handles these inputs well:

import { useForm } from 'react-hook-form';
import { useFormAutosave } from '@form-guardian/react';
import { useEffect } from 'react';

interface FormData {
country: string;
plan: string;
newsletter: boolean;
interests: string[];
}

function FormWithRHF() {
const { register, handleSubmit, setValue, getValues } = useForm<FormData>({
defaultValues: {
country: '',
plan: '',
newsletter: false,
interests: [],
},
});

const { formRef, restoreValues, clearDraft } = useFormAutosave(
'form-rhf',
{ autoRestore: false }
);

useEffect(() => {
restoreValues(
(field, value) => {
// Handle array values for checkboxes
if (field === 'interests' && Array.isArray(value)) {
value.forEach((val) => {
// Check the checkbox
const checkbox = document.querySelector(
`input[type="checkbox"][name="interests"][value="${val}"]`
) as HTMLInputElement;
if (checkbox) checkbox.checked = true;
});
} else {
setValue(field as keyof FormData, value, { shouldValidate: false });
}
},
() => getValues()
);
}, []);

const onSubmit = async (data: FormData) => {
await submitForm(data);
await clearDraft();
};

return (
<form ref={formRef} onSubmit={handleSubmit(onSubmit)}>
<select {...register('country', { required: true })}>
<option value="">Select country</option>
<option value="us">United States</option>
<option value="uk">United Kingdom</option>
</select>

<div>
<label>
<input type="radio" {...register('plan')} value="basic" />
Basic
</label>
<label>
<input type="radio" {...register('plan')} value="pro" />
Pro
</label>
</div>

<label>
<input type="checkbox" {...register('newsletter')} />
Newsletter
</label>

<div>
<label>
<input type="checkbox" {...register('interests')} value="tech" />
Tech
</label>
<label>
<input type="checkbox" {...register('interests')} value="sports" />
Sports
</label>
</div>

<button type="submit">Submit</button>
</form>
);
}

Handling Multiple Checkboxes

For multiple checkboxes with the same name:

function MultipleCheckboxes() {
const [selected, setSelected] = useState<string[]>([]);

const { formRef, clearDraft } = useFormAutosave('multiple-checkboxes', {
autoRestore: true,
});

const toggleCheckbox = (value: string) => {
setSelected(prev =>
prev.includes(value)
? prev.filter(v => v !== value)
: [...prev, value]
);
};

return (
<form ref={formRef}>
{['option1', 'option2', 'option3'].map((option) => (
<label key={option}>
<input
type="checkbox"
name="options"
value={option}
checked={selected.includes(option)}
onChange={() => toggleCheckbox(option)}
/>
{option}
</label>
))}
</form>
);
}

Custom Select Components

For custom select components (like react-select):

import Select from 'react-select';
import { useFormAutosave } from '@form-guardian/react';
import { useEffect, useRef } from 'react';

function CustomSelectForm() {
const selectRef = useRef<any>(null);
const { formRef, restoreValues, clearDraft } = useFormAutosave(
'custom-select-form',
{ autoRestore: false }
);

useEffect(() => {
restoreValues(
(field, value) => {
if (field === 'country' && selectRef.current) {
selectRef.current.setValue({ value, label: value });
}
},
() => ({
country: selectRef.current?.getValue()?.value || '',
})
);
}, []);

return (
<form ref={formRef}>
<Select
ref={selectRef}
name="country"
options={[
{ value: 'us', label: 'United States' },
{ value: 'uk', label: 'United Kingdom' },
]}
/>
</form>
);
}

Best Practices

  1. Use proper field names - Ensure radio buttons and checkboxes have the same name attribute
  2. Handle array values - Multiple checkboxes return arrays
  3. Test restoration - Verify that selected values are properly restored
  4. Use controlled components - For custom components, use controlled mode

Common Pitfalls

❌ Don't Forget Same Name for Radio Buttons

// ❌ Wrong - radio buttons won't work as a group
<input type="radio" name="plan1" value="basic" />
<input type="radio" name="plan2" value="pro" />

✅ Use Same Name for Radio Group

// ✅ Correct - radio buttons work as a group
<input type="radio" name="plan" value="basic" />
<input type="radio" name="plan" value="pro" />

Next Steps