thatgibbyguy
thatgibbyguy

Reputation: 4113

React radio input not checking

I have a simple form which has a couple of radio buttons that aren't checking. Each button has a change event attached, but still nothing changes. What can I do to not only capture their data, but signify that the input is selected?

The form

FormComponent = React.createClass({

  propTypes: {
    label: React.PropTypes.string,
    onChange: React.PropTypes.func
  },

  handleEvent(e) {
    let {onChange} = this.props;
    console.log(e);
  },

  render() {
    const {label} = this.props;
    return (
      <form className="lm-widget__form lm-flex-row">
        <fieldset className="lm-flex-row__column lm-h-flex-50">
          <RadioSet group='radio-group'
                    label={label}
                    radios={[
                      {
                        value: 'new',
                        checked: true,
                        changeEvent: this.handleEvent,
                        text: 'radio one'
                      },
                      {
                        value: 'old',
                        checked: false,
                        changeEvent: this.handleEvent,
                        text: 'radio two'
                      }
                    ]}
          />
        </fieldset>
      </form>
    )
  }

});

The radio buttons

RadioSet = React.createClass({
  propTypes: {
    group: React.PropTypes.string.isRequired,
    label: React.PropTypes.string,
    radios: React.PropTypes.arrayOf(
      React.PropTypes.shape({
        value: React.PropTypes.string.isRequired,
        checked: React.PropTypes.bool.isRequired,
        changeEvent: React.PropTypes.func.isRequired,
        text: React.PropTypes.string.isRequired
      })
    ).isRequired
  },

  render: function () {
    const {group, label, radios} = this.props;
    const self = this;

    if (label) {
      return(
        <div className="lm-widget-form__label">
          <div className="small">{label}</div>
          <div className="segment-controls">
            {radios.map(function(radio, i){
              return (
                <div key={i} className="segment-controls__group-item">
                  <input type="radio"
                          name={self.props.group}
                          className="segment-controls__button"
                          id={`radio-${i}`}
                          value={radio.value}
                          checked={radio.checked}
                          onChange={radio.changeEvent}
                  />

                  <label htmlFor={`radio-${i}`}
                         className="segment-controls__label">

                       <span className="segment-controls__label-text">
                             {radio.text}
                       </span>

                  </label>
                </div>
              );
            })
            }
          </div>
        </div>
      )
    }
    else {
      return (
        <div className="segment-controls">
          {this.props.radios.map(function(radio, i){
            return (
              <div key={radio.value} className="segment-controls__group-item">
                <input type="radio"
                        name={self.props.group}
                        className="segment-controls__button"
                        id={`radio-${i}`}
                        value={radio.value}
                        checked={radio.checked}
                        onChange={radio.changeEvent}
                />

                <label htmlFor={`radio-${i}`}
                       className="segment-controls__label">

                     <span className="segment-controls__label-text">
                           {radio.text}
                     </span>

                </label>
              </div>
            );
          })
          }
        </div>
      );
    }
  }
});

Upvotes: 1

Views: 1122

Answers (1)

winhowes
winhowes

Reputation: 8075

So the issue is that you're telling the first radio button it's checked every time by passing true to it.

If we change your first bit of code to use setState this should work.

FormComponent = React.createClass({

  getInitialState() {
      return {
          checkedIndex: 0
      };
  },

  propTypes: {
    label: React.PropTypes.string,
    onChange: React.PropTypes.func
  },

  handleEvent(index, e) {
    this.setState({
        checkedIndex: index
    });
    let {onChange} = this.props;
    console.log(e);
  },

  render() {
    const {label} = this.props;
    const radios = [
                      {
                        value: 'new',
                        checked: false,
                        changeEvent: this.handleEvent.bind(this, 0),
                        text: 'radio one'
                      },
                      {
                        value: 'old',
                        checked: false,
                        changeEvent: this.handleEvent.bind(this, 1),
                        text: 'radio two'
                      }
                    ];
    radios[this.state.checkedIndex].checked = true;
    return (
      <form className="lm-widget__form lm-flex-row">
        <fieldset className="lm-flex-row__column lm-h-flex-50">
          <RadioSet group='radio-group'
                    label={label}
                    radios={radios}
          />
        </fieldset>
      </form>
    )
  }

});

Also note we are using bind to maintain the this context of handleEvent and to pass in the proper index.

Upvotes: 2

Related Questions