Search code examples
reactjstwitter-bootstrapbootstrap-4frontendreactstrap

How to get state of Reactstrap's CustomInput Switch component, and how to map switches from an array?


        <FormGroup>
          <div>
            {this.props.diseases.map((disease, index) => (
              <FormGroup>
                <CustomInput
                  type="switch" 
                  id="exampleCustomSwitch"
                  key={disease}
                  disease={disease}
                  onClick={(disease) => this.props.toggle(disease)}
                  label={disease}
                />
              </FormGroup>
            ))
            }
          </div>
        </FormGroup>
  1. I want to be able to find out the state of the switch, whether it's switched on or off. Not sure how I'm able to do that? Am I to pass in a default value of some sort with 0 as off and 1 as on?

  2. Presently, the switches are mapping appropriately from the array, but switching on or off only works for the first switch. So, if I click on any of the other switches, for some reason the first switch toggles.


Solution

  • For point #1,yYou can use e.target.checked to check the true/false status for a particular CustomInput; Check this stackblitz to see it work

    For point #2 If you share your existing code, it will be easier to help with your specific scenario

    relevant js:

    class App extends Component {
      constructor() {
        super();
        this.state = {
          name: "World to React",
          log: []
        };
        this.customInputSwitched.bind(this);
      }
    
      customInputSwitched(buttonName, e) {
        let newStr = `we received ${e.target.checked} for ${buttonName}...`;
        console.log(newStr);
        let newLog = [...this.state.log, newStr];
        this.setState({ log: newLog });
      }
    
      render() {
        var testName = "modal for testing - click here";
        return (
          <div>
            <Hello name={this.state.name} />
            <p>Start editing to see some magic happen :)</p>
            <Form>
              <FormGroup>
                <Label for="exampleCheckbox">Switches</Label>
                <div>
                  <CustomInput
                    type="switch"
                    id="exampleCustomSwitch"
                    name="customSwitch"
                    label="Turn on this custom switch"
                    onChange={this.customInputSwitched.bind(this, "button1")}
                  />
                  <CustomInput
                    type="switch"
                    id="exampleCustomSwitch2"
                    name="customSwitch"
                    label="Or this one"
                    onChange={this.customInputSwitched.bind(this, "button2")}
                  />
                  <CustomInput
                    type="switch"
                    id="exampleCustomSwitch3"
                    label="But not this disabled one"
                    disabled
                  />
                  <CustomInput
                    type="switch"
                    id="exampleCustomSwitch4"
                    label="Can't click this label to turn on!"
                    htmlFor="exampleCustomSwitch4_X"
                    disabled
                  />
                </div>
              </FormGroup>
            </Form>
            {this.state.log}
          </div>
        );
      }
    }
    

    UPDATE #1: In light of questioner's comment below

    Few issues in your code at https://stackblitz.com/edit/react-rcqlwq

    • you have to instantiate Log in the state in the contstructor
    • the customInputSwitched function should pass the argument of the particular button, not a hard-coded 'button1' - so we add the index number of the disease
    • the ID of all the buttons can't be the same 'exampleCustomSwitch', so we just add the index number to ID
    • best practice in mapping as array is to include an index also, which has benefits (as shown in the next 2 points)

    relevant working JS for your code/stackblitz:

    class App extends Component {
      constructor() {
        super();
        this.state = {
          diseases: [
      "Normal",
      "Over inflated lungs",
      "Pneumonia",
      "Pneumothorax",
      "Congestive cardiac failure",
      "Consolidation",
      "Hilar enlargement",
      "Medical device",
      "Effusion"
    ],
    log: []
        };
        this.customInputSwitched.bind(this);
      }
    
      customInputSwitched(buttonName, e) {
        let newStr = `we received ${e.target.checked} for ${buttonName}...`;
        console.log(newStr);
        let newLog = [...this.state.log, newStr];
        this.setState({ log: newLog });
      }
    
      render() {
        return (
          <div>
            <p>Start editing to see some magic happen :)</p>
            <Form>
              <FormGroup>
                <Label for="exampleCheckbox">Switches</Label>
                {this.state.diseases.map((disease, index) => {
                  //console.log(disease, index);
                  let idName = "exampleCustomSwitch"+index;
    
                  return (
                  <div key={index}>
                    <CustomInput
                    type="switch"
                    id={idName}
                    name="customSwitch"
                    label={disease}
                    onChange={this.customInputSwitched.bind(this, "button"+index)}
                  />
                  </div>
                  );
                }
    
                )}
              </FormGroup>
            </Form>
            {this.state.log}
          </div>
        );
      }
    }