'Get user roles input using checkboxes and save in an array using useState() in react
I am creating an admin page where the admin can assign roles to other users. For this, I'm creating a front end input with checkboxes:
Now based on the options that the admin selects on front end, i want to send the roles data to backend in form of an array:
roles: ['admin', 'seller']
useState should be able to add / remove items to this array based on whether the associated cell is checked or unchecked.
const [roles, setRoles] = useState([]);
const checkBoxInputs = [
{
id: 1,
label: 'Admin',
value: 'admin',
},
{
id: 2,
label: 'Seller',
value: 'seller',
},
{
id: 3,
label: 'User',
value: 'user',
},
];
const [isChecked, setIsChecked] = useState(false);
const [roles, setRoles] = useState([]);
const handleCheckboxChange = (e) => {
setIsChecked(!isChecked);
if (isChecked) {
setRoles([...roles, roles.push(e.target.value)]);
} else {
setRoles([roles.filter(e.target.value)]);
}
};
console.log(values);
console.log(roles);
The app code:
<div>
<div className="mb-2 pb-1 border-b text-sm">
Choose user roles:
</div>
<ul className="flex items-center gap-1">
{checkBoxInputs.map((role, index) => (
<li key={index}>
<input
type="checkbox"
id={role.value}
name="roles"
value={role.value}
checked={isChecked}
onChange={handleCheckboxChange}
/>
<label htmlFor={role.value} className="text-sm ml-1">
{role.label}
</label>
</li>
))}
</ul>
</div>
Though the current implementation either checks or unchecks all inputs together.
Also, the values don't get removed from roles array when the checkboxes are checked out.
Update:
Sharing what worked for me:
const [roles, setRoles] = useState([]);
const handleCheckboxChange = (e) => {
if (e.target.checked) {
if (!roles.includes(e.target.value)) {
setRoles([...roles, e.target.value]);
}
} else {
var filteredRoles = roles.filter(function (value, index, arr) {
return value !== e.target.value;
});
setRoles(filteredRoles);
}
};
And the jsx code which worked:
<div>
<div className="mb-2 pb-1 border-b text-sm">
Choose user roles:
</div>
<ul className="flex items-center gap-1">
{checkBoxInputs.map((role, index) => (
<li key={index}>
<input
type="checkbox"
id={role.value}
name="roles"
value={role.value}
onChange={handleCheckboxChange}
/>
<label htmlFor={role.value} className="text-sm ml-1">
{role.label}
</label>
</li>
))}
</ul>
</div>
Note: I have been using tailwind css for the UI part in above code
Solution 1:[1]
you should check in checked
prop that checked value is equal to role.value
.And also you should push data either using push()
or spread operator.
const [roles, setRoles] = useState([]);
const checkBoxInputs = [
{
id: 1,
label: "Admin",
value: "admin"
},
{
id: 2,
label: "Seller",
value: "seller"
},
{
id: 3,
label: "User",
value: "user"
}
];
const [CheckedValue, setCheckedValue] = useState();
const handleCheckboxChange = (e) => {
if (e.target.checked) {
setCheckedValue(e.target.value);
if (!roles.includes(e.target.value)) {
setRoles([...roles, e.target.value]);
}
}
};
then in return statement
return (
<div>
<div className="mb-2 pb-1 border-b text-sm">Choose user roles:</div>
<ul className="flex items-center gap-1">
{checkBoxInputs.map((role, index) => (
<li key={index}>
<input
type="checkbox"
id={role.value}
name="roles"
value={role.value}
checked={role.value === CheckedValue}
onChange={handleCheckboxChange}
/>
<label htmlFor={role.value} className="text-sm ml-1">
{role.label}
</label>
</li>
))}
</ul>
</div>
);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Arik Patel |