How to validate a checkbox list in React
You may need to validate a checkbox list when you are creating a form in React. Just as we have created a common component for the select field and radio button in the previous article, here we will create a component for the checkbox list in React.
Checkout more articles on ReactJS
- Create a toggle switch in React
- How to implement a circular progress bar in React
- How to add Emoji Picker in the React
- Implement idle timeout popup in React
Demo Application
Output - How to validate a checkbox list in React - Clue Mediator
Steps to validate a checkbox list in React
1. Create a common component
Let’s create a reusable checkbox list component using Bootstrap where we will pass all required fields.
Same as the Input component and Select component, we have to go through a few more props to handle the validation such as `isReq`, `errorMsg`, `onValidateFunc`.
Checkbox.js
import React, { memo } from 'react';
import PropTypes from 'prop-types';
const changeHandler = (e, props) => {
let { value, checked } = e.target;
let newValue = [...props.value];
newValue = checked ? [...newValue, value] : newValue.filter(x => x !== value);
props.onChangeFunc(newValue, props.name, e);
if (!props.onValidateFunc) return;
let msg = null;
if (Array.isArray(newValue) && !newValue.length && props.isReq) {
msg = `Please select ${props.title}.`;
}
props.onValidateFunc(msg, props.name);
}
const Checkbox = props => {
const inputProps = {
type: "checkbox",
name: props.name,
className: props.className
}
return (
<div class={props.outerClassName}>
<label class="form-label">{props.title}</label>
<div>
{props.options.map((x, i) => <div key={i} class="{`form-check${props.isVertical" ?="" ''="" :="" `="" form-check-inline`}`}="">
<input {...inputprops}="" id={x.value} value={x.value} checked onchange="{e" ==""> changeHandler(e, props)} />
<label class="form-check-label" for={x.value}>
{x.label}
</label>
</div>)}
</div>
{props.errorMsg && <span class="text-danger">{props.errorMsg === true ? `Please select ${props.title}.` : props.errorMsg}</span>}
</div>
)
}
Checkbox.defaultProps = {
name: '',
title: '',
className: 'form-check-input',
outerClassName: 'mb-2',
isVertical: false,
value: [],
options: [],
onChangeFunc: () => { },
isReq: null,
onValidateFunc: () => { }
}
Checkbox.propTypes = {
name: PropTypes.string,
title: PropTypes.string,
className: PropTypes.string,
outerClassName: PropTypes.string,
isVertical: PropTypes.bool,
value: PropTypes.array,
options: PropTypes.array,
onChangeFunc: PropTypes.func,
isReq: PropTypes.bool,
errorMsg: PropTypes.any,
onValidateFunc: PropTypes.func
}
export default memo(Checkbox);
Here we have updated the `changeHandler` function to store the selected values of the checkboxes.
2. Create a form using common component
Now it’s time to use the Checkbox component in the main component for language and hobbies selection. In the first place, we have to define two different state variables called `form` and `error`.
Let’s define the object for each property in an error state. The error object contains the following attributes.
- `isReq` – For require validation
- `errorMsg` – To render the error message on the screen
- `onValidateFunc` – Function to handle the validation
const [form, setForm] = useState({
lang: ['english'],
hobbies: []
});
const onValidate = (value, name) => {
setError(prev => ({
...prev,
[name]: { ...prev[name], errorMsg: value }
}));
}
const [error, setError] = useState({
lang: {
isReq: true,
errorMsg: '',
onValidateFunc: onValidate
},
hobbies: {
isReq: true,
errorMsg: '',
onValidateFunc: onValidate
}
});
const onHandleChange = useCallback((value, name) => {
setForm(prev => ({
...prev,
[name]: value
}));
}, []);
In the above code, we have added a predefined value of the language. Now we have to slightly update the `validateForm` function as below.
const validateForm = () => {
let isInvalid = false;
Object.keys(error).forEach(x => {
const errObj = error[x];
if (errObj.errorMsg) {
isInvalid = true;
} else if (errObj.isReq && (Array.isArray(form[x]) ? !form[x].length : !form[x])) {
isInvalid = true;
onValidate(true, x);
}
});
return !isInvalid;
}
Let’s use the following HTML to render the form in the React component.
<div class="app">
<div class="mb-3"><strong>Validate a Checkbox list in React - <a href="https://www.cluemediator.com" target="_blank" rel="noreferrer noopener">Clue Mediator</a></strong></div>
<div class="form">
<checkbox name="lang" title="Language" value={form.lang} options={languageList} onchangefunc={onHandleChange} {...error.lang}="">
<checkbox name="hobbies" title="Hobbies" isvertical={true} value={form.hobbies} options={hobbiesList} onchangefunc={onHandleChange} {...error.hobbies}="">
<button class="btn btn-primary btn-sm mt-2" onclick={handleSubmit}>
Submit
</button>
</checkbox></checkbox></div>
</div>
Let’s write all the code together and see how it looks.
App.js
import React, { useState, useCallback } from 'react';
import Checkbox from './Checkbox';
const languageList = [
{ value: "english", label: "English" },
{ value: "hindi", label: "Hindi" },
{ value: "spanish", label: "Spanish" },
{ value: "arabic", label: "Arabic" }
];
const hobbiesList = [
{ value: "music", label: "Music" },
{ value: "gaming", label: "Gaming" },
{ value: "blogging", label: "Blogging" },
{ value: "reading", label: "Reading" }
];
function App() {
const [form, setForm] = useState({
lang: ['english'],
hobbies: []
});
const onValidate = (value, name) => {
setError(prev => ({
...prev,
[name]: { ...prev[name], errorMsg: value }
}));
}
const [error, setError] = useState({
lang: {
isReq: true,
errorMsg: '',
onValidateFunc: onValidate
},
hobbies: {
isReq: true,
errorMsg: '',
onValidateFunc: onValidate
}
});
const onHandleChange = useCallback((value, name) => {
setForm(prev => ({
...prev,
[name]: value
}));
}, []);
const validateForm = () => {
let isInvalid = false;
Object.keys(error).forEach(x => {
const errObj = error[x];
if (errObj.errorMsg) {
isInvalid = true;
} else if (errObj.isReq && (Array.isArray(form[x]) ? !form[x].length : !form[x])) {
isInvalid = true;
onValidate(true, x);
}
});
return !isInvalid;
}
const handleSubmit = () => {
const isValid = validateForm();
if (!isValid) {
console.error('Invalid Form!');
return false;
}
console.log('Data:', form);
}
return (
<div class="app">
<div class="mb-3"><strong>Validate a Checkbox list in React - <a href="https://www.cluemediator.com" target="_blank" rel="noreferrer noopener">Clue Mediator</a></strong></div>
<div class="form">
<checkbox name="lang" title="Language" value={form.lang} options={languageList} onchangefunc={onHandleChange} {...error.lang}="">
<checkbox name="hobbies" title="Hobbies" isvertical={true} value={form.hobbies} options={hobbiesList} onchangefunc={onHandleChange} {...error.hobbies}="">
<button class="btn btn-primary btn-sm mt-2" onclick={handleSubmit}>
Submit
</button>
</checkbox></checkbox></div>
</div>
);
}
export default App;
3. Output
Run the application and check the output in the browser.
I hope you find this article helpful.
Thank you for reading. Happy Coding..!! 🙂