1

Checkbox generated based on data

This checkbox [ looks like toggle button] generated based on data. I want to get checked values in an array.

Code

{this.state.customersmsselect.map((e, key) => {
  
  if(e.isactive == "ON"){
  return (
    <div key={key}>
      <div className="form-group col-md-8">
        <label className="col-md-4 control-label">{e.notificationtype}</label>
        <div className="col-md-4 smart-form">
          <label className="toggle">
            <input type="checkbox" id={"smscheckbox" + key} value={e.isactive + "," + e.smstemplateid} name={"checkbox-toggle"+e.smstemplateid} onChange={this.onChangeFavorite} defaultChecked />
            <i data-swchoff-text='OFF' data-swchon-text='ON' ></i>
        </label>
      </div>
    </div>
    <div style={{ margin: 10 }}>&nbsp;</div>
    </div>
  );

My onChange method

If click on that button then I will get, that button's name.

   onChangeFavorite(event) {
     if(!event.target.checked){
        console.log(event.target.name);
     }
   };

My customersmsselect array looks like

0: {smstemplateid: "1", notificationtype: "Invoice Details", isactive: "ON"}
1: {smstemplateid: "2", notificationtype: "Payment Thank-You", isactive: "ON"}
2: {smstemplateid: "3", notificationtype: "Daily Closing Balance", isactive: "OFF"}
3: {smstemplateid: "4", notificationtype: "Monthly Closing Balance", isactive: "ON"}

Problem

I want to get all the checked values in an array when I click on the button.

3
  • looks like duplicate : stackoverflow.com/questions/590018/… Commented Sep 9, 2019 at 11:48
  • 1
    I want a solution to react, I do not want to use Jquery to manipulate DOM Commented Sep 9, 2019 at 11:50
  • You have to capture the CheckBox state in the OnChange event and store it in a state object. Then get the values from State whenever required Commented Sep 9, 2019 at 11:59

3 Answers 3

1

Here we can instead use controlled inputs. Then we need to bind the checked attribute and set the state in onChange handler. checked={e.isactive === "ON"} checks the checkbox depending on the value. onChange={()=>this.onChangeFavorite(e)} will attach the event handler along with the customersmsselect item which is being mapped.

x.isactive = x.isactive === "OFF" ? "ON" : "OFF";
        this.setState({
          customersmsselect: this.state.customersmsselect
});

Does the required checking of the input.

{this.state.customersmsselect.map((e, key) => {
  $('#s').val(key);
  if(e.isactive == "ON"){
  return (
    <div key={key}>
      <div className="form-group col-md-8">
        <label className="col-md-4 control-label">{e.notificationtype}</label>
        <div className="col-md-4 smart-form">
          <label className="toggle">
            <input type="checkbox" id={"smscheckbox" + key} value={e.isactive + "," + e.smstemplateid} name={"checkbox-toggle"+e.smstemplateid} onChange={()=>this.onChangeFavorite(e)} checked={e.isactive === "ON"} />
            <i data-swchoff-text='OFF' data-swchon-text='ON' ></i>
        </label>
      </div>
    </div>
    <div style={{ margin: 10 }}>&nbsp;</div>
    </div>
  );

Then

onChangeFavorite(x) {
     //Here now we are directly changing the array element value. 
     //Since its in the state when we change and assign it will automatically
     //update the controlled components.


    x.isactive = x.isactive === "OFF" ? "ON" : "OFF";
    this.setState({
      customersmsselect: this.state.customersmsselect
    });
};
Sign up to request clarification or add additional context in comments.

1 Comment

If you have doubts on this solution feel free to ask.
1

you can try use ref like this:

{this.state.customersmsselect.map((e, key) => {
  $('#s').val(key);
  if(e.isactive == "ON"){
  return (
    <div key={key}>
      <div className="form-group col-md-8">
        <label className="col-md-4 control-label">{e.notificationtype}</label>
        <div className="col-md-4 smart-form">
          <label className="toggle">
            <input type="checkbox" id={"smscheckbox" + key} value={e.isactive + "," + e.smstemplateid} name={"checkbox-toggle"+e.smstemplateid} onChange={this.onChangeFavorite} defaultChecked ref={node => { this.checkBoxes[key] = node; }} />
            <i data-swchoff-text='OFF' data-swchon-text='ON' ></i>
        </label>
      </div>
    </div>
    <div style={{ margin: 10 }}>&nbsp;</div>
    </div>
  );

then you can refer to this.checkBoxes as a regular array

2 Comments

I think ref is not required here. We can achieve this without ref.
agree for the way you mentioned.
1

Your input field:

<input type="checkbox" id={"smscheckbox" + key} value={e.isactive} name={"checkbox-toggle"+e.smstemplateid} onChange={(event) => this.onChangeFavorite(event, key)} checked={e.isactive === "ON"} />

Your onChange event:

onChangeFavorite(event, index) {
  const shouldBeOnOrOff =
    this.state.customersmsselect[index].isactive === "ON" ? "OFF" : "ON";
  this.setState({
    customersmsselect: this.state.customersmsselect.map((item, i) =>
      index === i ? { ...item, isactive: shouldBeOnOrOff } : item
    )
  });
}

This will give you an array of objects that are currently ON:

this.state.customersmsselect.filter((item) => item.isactive === "ON");

This will give you an array of IDs that are currently ON, which I assume is the value you want?

this.state.customersmsselect.filter((item) => item.isactive === "ON").map((item) => item.smstemplateid);

DEMO: https://codesandbox.io/s/quiet-morning-j6dbx?fontsize=14

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.