lagertha6
lagertha6

Reputation: 39

How to get all checkbox IDs that are checked using Javascript?

I'm working on a project named "Food Recipes", where a user can create, edit, delete his own recipes.

When creating a new recipe, the user must select the ingrediets. So here is where I need your help:

By an axios call, I'm getting all the ingredients and show them into a table. The table looks like this:

|---------------------|------------------|-----------------|
|      Ingredient     |    Check         |     Amount      |
|---------------------|------------------|-----------------|
|      Tomato         |     true         |      2 kg       |
|---------------------|------------------|-----------------|
|      Potato         |     false        |                 |
|---------------------|------------------|-----------------|
|      Onion          |     true         |      1 kg       |
|---------------------|------------------|-----------------|

After checking some ingredient to TRUE, I want to have onChange function that will create list of IDs, from all ingredients that are CHECKED (in this case, I will have list with two elements: ID from Tomato, and ID from Onion)

To mention, i put ingredient ID as a value inside the <input type="checkbox"/>

Here is my code:

import React, {Component, useEffect, useState} from 'react'
import axios from "../../../axios/axios"

class Ingredient extends Component {
    constructor(props){
        super(props)
        this.state = {
            ingredients: [],
            ingedientsList: [],
            isChecked: false,
        }
    }
    onIngredientChange = (e) => {
          //HERE
    };

    componentDidMount() {
        axios.get("/ingredients").then((data) => {
            const ingredients = Object.keys(data.data).map((ingredient, index) => {
                return (
                    <tr key={index}>
                        <td scope="col">
                            <label>{data.data[index].name}</label>
                        </td>
                        <td scope="col">
                            <input
                                id={data.data[index].id}
                                key={index}
                                type="checkbox"
                                name={"newIngredients"}
                                value={data.data[index].id}
                                onChange={this.onIngredientChange}

                            />
                        </td>
                        <td scope="col">
                            <input
                                id={data.data[index].id + "amount"}
                                key={index}
                                type="number"
                                min="0"
                                max="500"
                                name="amount"
                                placeholder="grams"
                                onChange={this.onIngredientChange}
                            />
                        </td>
                    </tr>
                );
            });
            this.setState({ingredients: ingredients});
        });
    }
    render() {
        return (
            <div className="form-group">
                <table className="table tr-history table-striped small">
                    <thead>
                    <tr>
                        <th scope="col">
                            <h5>Ingredient</h5>
                        </th>
                        <th scope="col">
                            <h5>Check</h5>
                        </th>
                        <th scope="col">
                            <h5>Amount</h5>
                        </th>
                    </tr>
                    </thead>
                    <tbody>
                    {this.state.ingredients}
                    </tbody>
                </table>
            </div>
        )
    }
}
export default Ingredient;

Upvotes: 0

Views: 5532

Answers (3)

Kuo-hsuan Hsu
Kuo-hsuan Hsu

Reputation: 687

Update

Try the code below.

const data = {
   data:[
     {
       id:1,
       name:"A"
     },
     {
       id:2,
       name:"B"
     },
     {
       id:3,
       name:"C"
     }
   ]
}


class Ingredient extends React.Component {
    constructor(props){
        super(props)
        this.state = {
          ingredients: [],
          ingedientsList: [],
          checkedList:[],
          isChecked: false,
        }
    }
    
        componentDidMount() {
            const ingredients = data.data.map((ingredient, index) => {
                return (
                    <tr key={index}>
                        <td scope="col">
                            <label>{data.data[index].name}</label>
                        </td>
                        <td scope="col">
                           <input
                              id={data.data[index].id}
                              key={index}
                              type="checkbox"
                              name={"newIngredients"}
                              value={data.data[index].id}    
                              onChange={(e)=>this.onIngredientChange(e,data.data[index].id)}
                            />
                        </td>
                        <td scope="col">
                            <input
                                id={data.data[index].id + "amount"}
                                key={index}
                                type="number"
                                min="0"
                                max="500"
                                name="amount"
                                placeholder="grams"
                                onChange={this.onIngredientChange}
                            />
                        </td>
                    </tr>
                );
            });
            this.setState({ingredients: ingredients});
    }
    
     onIngredientChange = (e,id) => {
     let resultArray = []
     if(e.target.checked)      //if checked (true), then add this id into checkedList
     {
          resultArray = this.state.checkedList.filter(CheckedId=>
            CheckedId !== id
          )
          resultArray.push(id) 
     }
     else                    //if not checked (false), then remove this id from checkedList
     {
        resultArray = this.state.checkedList.filter(CheckedId=>
            CheckedId !== id
        )
     }
     console.log(resultArray)

     this.setState({
        checkedList:resultArray
     })
     }
    
    
    
    render() {
        return (
            <div className="form-group">
                <table className="table tr-history table-striped small">
                    <thead>
                    <tr>
                        <th scope="col">
                            <h5>Ingredient</h5>
                        </th>
                        <th scope="col">
                            <h5>Check</h5>
                        </th>
                        <th scope="col">
                            <h5>Amount</h5>
                        </th>
                    </tr>
                    </thead>
                    <tbody>
                    {this.state.ingredients}
                    </tbody>
                </table>
            </div>
        )
    }
}
// Render it
ReactDOM.render(
  <Ingredient />,
  document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>

First, have a checked list in state

    this.state = {
        ingredients: [],
        ingedientsList: [],
        checkedList:[]
        isChecked: false,
    }

Then change element a little bit,

   <input
       id={data.data[index].id}
       key={index}
       type="checkbox"
       name={"newIngredients"}
       value={data.data[index].id}    
       onChange={(e)=>this.onIngredientChange(e,data.data[index].id)}
    />

Then change handler,

onIngredientChange = (e,id) => {
     let resultArray = []
     if(e.target.checked)      //if checked (true), then add this id into checkedList
     {
        resultArray = this.state.checkedList.filter(CheckedId=>
            CheckedId !== id      //  filter(checkID=>{CheckedId !== id}) remove {} 
        )
        resultArray.push(id)
     }
     else                    //if not checked (false), then remove this id from checkedList
     {
        resultArray = this.state.checkedList.filter(CheckedId=>
            CheckedId !== id      //  filter(checkID=>{CheckedId !== id}) remove {} 
        )
     }

     this.setState({
        checkedList:resultArray
     })

     console.log(resultArray)   // get all checked ID
};

Upvotes: 1

Aleksey Polonka
Aleksey Polonka

Reputation: 583

...
onIngredientChange = e => {
  const checkedIngrediants = {
    ...this.state.checkedIngrediants
    [e.target.id]: !e.target.value
  };
  this.setState({
    checkedIngredients,
    ingredientsList: Object.keys(checkedIngredients)
      .filter(key => checkedIngredients[key])
  })
}
...
<input
  id={data.data[index].id}
  key={index}
  type="checkbox"
  name={"newIngredients"}
  value={this.state.checkedIngrediants[data.data[index].id]}
  onChange={this.onIngredientChange} />

Upvotes: 0

Arun Mohan
Arun Mohan

Reputation: 1227

Try this. Use a state array instead of simple array.

onIngredientChange = (e, value) => {
         if (array.includes(value) && !e.target.checked) {
           array.splice( array.indexOf(value), 1 );
         } else if (!array.includes(value) && e.target.checked) {
           array.push(value)
         }
    };

<input id={data.data[index].id} key={index}
    type="checkbox" name={"newIngredients"}
     value={data.data[index].id}
     onChange={(e) =>this.onIngredientChange(e, value)} />

Upvotes: 0

Related Questions