admin管理员组

文章数量:1355532

I have a Form ponent that I am building in React and this form has some Field ponents as children. I am using these ponents to build a log in form that has an email address and password. My form has an onSubmit handler that serializes its children (Fields) and sends off an AJAX request.

Everything is working well in the normal case. But, when browsers like Chrome Autofill the form with my email address and password, the serialization doesn't pick up the values of the inputs.

Field currently looks something like this:

/** @jsx React.DOM */

var Field = React.createClass({
  serialize: function() {
    return { name: this.props.name, value: this.refs.field.state.value };
  },

  render: function() {
    return (
      <div>
        <label>
          {this.props.label}
          <input type={this.props.type} ref="field"
            name={this.props.name}
            defaultValue={this.props.value} />
        </label>
      </div>
    )
  }
});

How do I get the browser Autofill value to show up in my serialized Field data?

I have a Form ponent that I am building in React and this form has some Field ponents as children. I am using these ponents to build a log in form that has an email address and password. My form has an onSubmit handler that serializes its children (Fields) and sends off an AJAX request.

Everything is working well in the normal case. But, when browsers like Chrome Autofill the form with my email address and password, the serialization doesn't pick up the values of the inputs.

Field currently looks something like this:

/** @jsx React.DOM */

var Field = React.createClass({
  serialize: function() {
    return { name: this.props.name, value: this.refs.field.state.value };
  },

  render: function() {
    return (
      <div>
        <label>
          {this.props.label}
          <input type={this.props.type} ref="field"
            name={this.props.name}
            defaultValue={this.props.value} />
        </label>
      </div>
    )
  }
});

How do I get the browser Autofill value to show up in my serialized Field data?

Share Improve this question edited May 6, 2014 at 4:58 Joe Lencioni asked May 2, 2014 at 16:13 Joe LencioniJoe Lencioni 10.5k18 gold badges57 silver badges68 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 3

State should flow in one direction, from the top layer down to the bottom. So reaching into a child element to get its state is a bad idea. To acplish the serialization with this structure, you simply need to reach into the DOM to get the value of the input. In the code example above, the serialize method should be:

serialize: function() {
  return { name: this.props.name, value: this.refs.field.getDOMNode().value };
},

Using onChange event is the most mon scenario to update whatever model property bound to a ponent, but you can also use onBlur to catch the values when the form is "auto-filled" by the browser.

var Input = React.createClass({
  getInitialState: function() {
    return {typed: ''};
  },
  onBlur: function(event) {
    this.setState({typed: event.target.value});
  },
  render: function() {
    return <div>
        <input type="text" onBlur={this.onBlur.bind(this)}/>
        You typed: <code>{this.state.typed}</code>
      </div>
  }
});

This is my solution using refs :) ..basically I trigger the change events manually for the first second..the reason behind is that every browser is handling autofill in a different way and this changes based on browser version..there is no way to cover this properly as of now

  ponentDidMount () {
    let tries = 4;
    this.int  = setInterval(() => {
      tries--;
      if (tries === 0) {
        this._createChangeEvent();
        clearInterval(this.int);
      }
    }, 300);
  }

  _createChangeEvent = () => {
    if ("createEvent" in document) {
      const evt = document.createEvent("HTMLEvents");
      evt.initEvent("change", false, true);
      this.input.dispatchEvent(evt);
    } else {
      this.input.fireEvent("onchange");
    }
  };

本文标签: