0

one of my application section allows users to select mu;tiple options by selecting individual checkboxes in React by populating the Item to checkboxes. I wrote a code to handle onChange of the check box to send the _id to backend API.

The problem I'm facing when clicking one checkbox all checkboxes are getting selected. I need the app to able to check one checkbox at a time and capture its key id.

my code is;

const fetchCategory = async () => {
    fetch(`http://localhost:4000/api/v1/category`)
    .then(response => response.json())
    .then(response => {
    console.log("response: ", response.categories);
    if (response.success === true) {
        setCategoryList(response.categories)
        // setIsLoading(false)
    } else {
        alert(response.message)
    }
},
(error) => {
    alert('Fetch faied: ' + error)
})
}

const [checked, setChecked] = useState(false);

const chechboxClickHandler = (id, event) => {
    setChecked(!checked)
    console.log(event);

    if (!checked) {
        console.log(!checked);
        console.log("category id: ", id);
    }        
}

return (
    <div className="card">
        <div className="card-body">
            <div className="row">
               {categoryList && categoryList.map(c => (
                   <React.Fragment>
                       <div className="col-md-3 d-flex align-items-center">
                           <div class="form-check card">
                               <img src={`http://localhost:4000/api/v1/category/icon/${c.icon}`} width="50" height="50" alt={c.icon} />
                               <input class="form-check-input" type="checkbox" name="exampleRadios" id="exampleRadios1" value="option1" checked={checked} onChange={(event) => chechboxClickHandler(c._id, event)} />
                                <label class="form-check-label" for="exampleRadios1">
                                            {c.title}
                                </label>
                            </div>
                       </div>
                   </React.Fragment>
                 ))}
            </div>
        </div>
    </div>
)

1 Answer 1

1

The problem is that you have an array of categories, but you hold a singular boolean for all of the checkboxes in state. It may look like you have multiple checkboxes, but you only have one boolean that represents the clicked state of all of them. Depending on the approach you want to take, you can add a isChecked attribute with the categories, or can hold an array that would hold the ids of the selected categories. I would recommend holding an additional array that holds the ids of the selected categories, because it may be not optimal to manipulate the categories.


New State:

const [checked, setChecked] = useState([]);

Push the id of selected category to the checked array

const chechboxClickHandler = (id, event) => {
    const cpyChecked = [...checked];

    const indexOfId = cpyChecked.indexOf(id);
    if(indexOfId === -1) {
        cpyChecked.push(id);
    }
    else {
        cpyChecked.splice(indexOfId, 1);
    }

    setChecked(cpyChecked);     
}

Render:

<div class="form-check card">
                               <img src={`http://localhost:4000/api/v1/category/icon/${c.icon}`} width="50" height="50" alt={c.icon} />
                               <input class="form-check-input" type="checkbox" name="exampleRadios" id="exampleRadios1" value="option1" checked={checked.includes(c._id)} onChange={(event) => chechboxClickHandler(c._id, event)} />
                                <label class="form-check-label" for="exampleRadios1">
                                            {c.title}
                                </label>
                            </div>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.