So ,I am trying to make some checkboxes in a pop up filter menu on click of a button. Below here is the common code for the pop up menu
const MenuPop = ({onClose , visible, isLoading,item,values}) => {
const handleClose = (e)=>{
e.preventDefault()
if(e.target.id==='parent'){
onClose()
}
}
if(!visible)
return null;
return (
<div
id="parent"
className={`${values} fixed z-[100] inset-0 bg-[black] bg-opacity-50`}
onClick={handleClose}
>
{item}
</div>
)
}
here are the different variables that I have used as props using a React hook
const useCommonItems = () => {
const [visible, setvisible] = useState(false)
const handleClose =()=>{
setvisible(false)
}
return {
visible,
setvisible,
handleClose
}
}
here is my page where I have a button the opens the pop up menu on the click of a button
const App=()=>{
const {visible,setvisible,handleClose}=useCommonItems();//react hook to get commonly used variables
return (
<>
<button onClick={e=>{
e.preventDefault();
//making the visible = true
setvisible(true)
}>Click Me </button>
<MenuPop visible={visible} onClose={handleClose} values="flex justify-center items-
center" item={<Filter/>} />
<>
);}
here is the component that opens up as soon as the button "Click Me" above is click
const Filter = () => {
const PriceArray = ["100", "300", "1000", "2000"];
const [priceVariable, setPriceVariable] = useState(0);
console.log(priceVariable)
const headingClass = "text-[20px] text-blue-600 font-semibold";
const inputClass =
"mr-[15px] border-[2px] font-[300] w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600 accent-blue-600 ";
const parentCaseClass = "border-b-[2px] border-blue-600 mb-[20px] pb-[20px]";
return (
<div className="bg-[white] 450:w-[450px] w-[100%] p-[20px] rounded-[20px] grid grid-flow-row grid-cols-1 450:grid-cols-2">
<div className={`Price ${parentCaseClass} `}>
<p className={`${headingClass}`}>Price</p>
{PriceArray.map((item, id) => (
<div className="" key={id}>
<input type="checkbox" value={item} id={name} name={item} className={inputClass} />
<label htmlFor={item}>{item}</label>
</div>
))}
</div>
</div>
);
};
So why are the checkboxes not working on clicking them?Can someone help?
A checkbox should have a checked
attribute which holds a boolean value. More information here.
What you can do is create a checkbox component like this:
const Checkbox = ({ checked, onChange, id, className }) => {
return (
<input
id={id}
className={className}
checked={checked}
type="checkbox"
onChange={onChange}
/>
);
};
Use it like this:
// import or create a constant called SOME_CHECKBOX_NAME_CONSTANT
// that holds the label names
const Component = () => {
const [data, setData] = useState({
isSomeUseCaseData: false,
});
const onChangeCheckbox = (event) => {
setData({ isSomeUseCaseData: event.target.checked });
};
return (
<div className="some-form-name">
{Object.keys(data).map((item) => (
<Checkbox
key={item}
id={`${item}-id`}
checked={data[item]}
onChange={onChangeCheckbox}
className="some-class-name"
>
<span>{SOME_CHECKBOX_NAME_CONSTANT[item]}</span>
</Checkbox>
))}
</div>
);
};
Now you have a controlled checkbox. Your Filter
component might look like this:
const Filter = () => {
const PriceArray = ['100', '300', '1000', '2000'];
const [priceVariable, setPriceVariable] = useState(0);
const [data, setData] = useState({});
const headingClass = 'text-[20px] text-blue-600 font-semibold';
const inputClass = 'mr-[15px] border-[2px] font-[300] w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600 accent-blue-600 ';
const parentCaseClass = 'border-b-[2px] border-blue-600 mb-[20px] pb-[20px]';
return (
<div className="450:w-[450px] 450:grid-cols-2 grid w-[100%] grid-flow-row grid-cols-1 rounded-[20px] bg-[white] p-[20px]">
<div className={`Price ${parentCaseClass} `}>
<p className={`${headingClass}`}>Price</p>
{PriceArray.map((item, id) => (
<div
className=""
key={id}
>
<Checkbox
value={item}
id={name}
name={name}
className={inputClass}
checked={data[item] || false}
onChange={(e) => {
setData(() => ({ ...data, [item]: e.target.checked }));
}}
/>
<label htmlFor={item}>{item}</label>
</div>
))}
</div>
</div>
);
};
Audience please don't curse me in the comments, I did not have time to refactor @randeepsarma24's code.