React checkbox if checked add value to array
Asked Answered
K

6

5

Hi this might be a very newbie question to ask but here is my question. I have check boxes that represent all the days of the week. If a day is checked I want to add it to a array so that on submit I can pass the array to back-end. I copied check box structure from bootstrap to start with. I tried to add logic to see if a box is checked and if it is checked I want to push it to my empty array in state. Also if a checkbox was checked but then unchecked I want to remove the item from the state array. So far I haven't found a way to make this all work.

import React from 'react'

class CalenderSettingsModal extends React.Component {
    constructor(props) {
        super(props);
        this.state={
            workStart: 8,
            workEnd: '',
            workDays:[],

        }

        handleCheckboxChange = (event)=> this.setState({workDays: event.target.value});


    }

    render() {


        return (
            <React.Fragment>
                        <form>
                            <div>
                                <h5>Select your workday(s):</h5>
                                <div class="custom-control custom-checkbox " >
                                    <input type="checkbox" class="custom-control-input" id="monday" value="monday"  onChange={this.handleCheckboxChange}/>
                                    <label class="custom-control-label" for="monday">Monday</label>

                                </div>
                                <div class="custom-control custom-checkbox">
                                    <input type="checkbox" class="custom-control-input" id="tuesday" value="tuesday" onChange={ this.handleCheckboxChange}/>
                                    <label class="custom-control-label" for="tuesday">Tuesday</label>

                                </div>

                        </form>
                            <button >Save settings</button>



            </React.Fragment>

        );
    }
}

export default CalenderSettingsModal;

With this so far I tried to accomplish assigning the value to workDays when the box is checked but isn't working and I'm not sure how I could accomplish what I want to do. Any insight would be appreciated.

Krill answered 24/5, 2020 at 13:10 Comment(0)
B
12

Right now, you are assigning the workDays array to a string type.

You can use the spread operator to add values to your workDays state array. If event.target.id is already present in the workDays state you can filter it. Here is the working code snippet.

Edit reverent-franklin-ziqrn

 handleCheckboxChange = event => {
    let newArray = [...this.state.workDays, event.target.id];
    if (this.state.workDays.includes(event.target.id)) {
      newArray = newArray.filter(day => day !== event.target.id);
    } 
    this.setState({
      workDays: newArray
    });
  };
Browbeat answered 24/5, 2020 at 13:53 Comment(1)
my question is like your answer , please check this question: #74996545Ceilidh
A
3

See if this helps.

class CalenderSettingsModal extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      workStart: 8,
      workEnd: '',
      workDays: [],
    }
  }

  handleCheckboxChange = (event) => {
    if (event.target.checked) {
      if (!this.state.workDays.includes(event.target.value)) {
        this.setState(prevState => ({ workDays: [...prevState.workDays, event.target.value]}))
      }
    } else {
      this.setState(prevState => ({ workDays: prevState.workDays.filter(day => day !== event.target.value) }));
    }
  }


  render() {
    return (
      <React.Fragment>
        <form>
          <div>
            <h5>Select your workday(s):</h5>
            <div class="custom-control custom-checkbox" >
              {
                ["Monday", "Tuesday", /*... */].map(day => {
                  return (
                    <div class="custom-control custom-checkbox">
                      <input type="checkbox" class="custom-control-input" id={day} value={day} onChange={this.handleCheckboxChange} />
                      <label class="custom-control-label" for={day}>{day}</label>
                    </div>
                  )
                })
              }
            </div>
          </div>
        </form>
        <button >Save settings</button>
      </React.Fragment>

    );
  }
}
Augustus answered 24/5, 2020 at 13:55 Comment(1)
thank you for your answer. I'm getting this error when I checked a box TypeError: Cannot read property 'value' of nullKrill
G
2

note: in order to run it properly you need to install react boostrap by the below command.

npm i react-bootstrap

The question is answered but my code will help those who want to achieve it in react functional components, just copy paste the code and you will be able to know the logic behind it. I am using react bootstrap you can use anything, the concept is the same.

import React, {useState } from "react";
import Form from "react-bootstrap/Form";
import 'bootstrap/dist/css/bootstrap.min.css';

function RolesList(props) {


const [permissions,setPermissions] = useState([]);


const handleCheck = (event) => {
  var permissions_array = [...permissions];
  if (event.target.checked) {
    permissions_array = [...permissions, event.target.value];
  } else {
    permissions_array.splice(permissions.indexOf(event.target.value), 1);
  }
  setPermissions(permissions_array);

};


  return (
    <>
     
 <form> 
     <Form.Check 
        type={'checkbox'}
        name={"permission"}
        id={'permission'}
        label={'permission1'}
        value={'1'}
        onChange={handleCheck}

      />

<Form.Check 
        type={'checkbox'}
        name={"permission"}
        id={'permission'}
        label={'permission2'}
        value={'2'}
        onChange={handleCheck}

      />

</form>


    </>

)

}



export default RolesList

the code above will update the hooks likewise: enter image description here

Greenberg answered 21/5, 2022 at 8:10 Comment(0)
H
1

It's not necessary to keep an array of what boxes are checked. You can easily collect all the checked boxes when you save your data.

const checkedBoxes = document.querySelectorAll('input[type=checkbox]:checked');

If you have different groups of checkboxes, you can use a unique class to identify the group:

const checkedBoxes = document.querySelectorAll('input[class=unique-class]:checked');
Homemaking answered 24/5, 2020 at 13:59 Comment(0)
M
1

I've done it with functional component here's the code. Use the useEffect hook to console.log the latest value. If you console.log directly in the handleChange method, you will be 1 value behind from the latest value.

Available for any help.

        import React, { useState, useEffect } from "react";
    
        export default function App() {
        const [dataArray, setdataArray] = useState([]);
    
        const handleChange = (e)=>{
        // setisChecked(e.target.checked);
        if(e.target.checked === true){
          setdataArray([...dataArray, e.target.value]);
        }
        else if(e.target.checked === false){
          let freshArray = dataArray.filter(val => val !== e.target.value);
          setdataArray([...freshArray]);
        }
      }
    
      useEffect(()=>{
    
        console.log(dataArray);
    
      }, [dataArray]);
    
    
      return (
        <>
        <input 
          type="checkbox"
          value='Monday'
          onChange={e => handleChange(e)} 
          />
          <span>Monday</span>
    
        <input 
          type="checkbox"
          value='Tuesday'
          onChange={e => handleChange(e)} 
          />
          <span>Tuesday</span>
        <input 
          type="checkbox"
          value='Wednesday'
          onChange={e => handleChange(e)} 
          />
          <span>Wednesday</span>
        <input 
          type="checkbox"
          value='Thursday'
          onChange={e => handleChange(e)} 
          />
          <span>Thursday</span>
        <input 
          type="checkbox"
          value='Friday'
          onChange={e => handleChange(e)} 
          />
          <span>Friday</span>
        <input 
          type="checkbox"
          value='Saturday'
          onChange={e => handleChange(e)} 
          />
          <span>Saturday</span>
        <input 
          type="checkbox"
          value='Sunday'
          onChange={e => handleChange(e)} 
          />
          <span>Sunday</span>
        </>
      )
    }
Mikes answered 15/8, 2022 at 3:13 Comment(0)
H
0
const [category_check_list, setCategoryCheckList] = useState([]);
const categoryCheckboxFilterHandler = e => {
    if (e.target.checked == true){
        setCategoryCheckList([...category_check_list, Number(e.target.value)]);
    }else{
        let check_list = [];
        category_check_list.map(check => {
            if (Number(check) != Number(e.target.value)){
                check_list.push(Number(check));
            }
        });
        setCategoryCheckList(check_list);
    }
};
var checked_category_id_list = category_check_list.toString();

then in the return i placed the following code and it worked perfect for me cause now its dynamic

return(
<>
 {categoriesQuery.isLoading ? (
   <span>Loading...</span>
    ) : categoriesQuery.isError ? (
    categoriesQuery.error.message
    ) : (
    categoriesQuery.data.slice(0, list_limit).map((category) => (
    <Grid item key={category.id} >
     <Paper className={paper}>
      <div className="form-check">
 <label htmlFor={category.id} className="form-check-label-form_check_label">
 <input className="form-check-label form_checkbox" type="checkbox" 
        name={category.category_name} value={category.id}  id={category.id} 
        onChange={e => categoryCheckboxFilterHandler(e)} />
             {category.category_name}
   </label>
                       </div>
               </Paper>
            </Grid>
         ))
             )}
   <>
)

i was using the material UI design hence the Grid and Paper, you can alternatively replace with div

Hans answered 4/8, 2021 at 14:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.