Skip to content
This repository has been archived by the owner on Feb 16, 2021. It is now read-only.

refs.form.getValue() should return auto-complete values #102

Closed
webmasterkai opened this issue Apr 9, 2015 · 3 comments
Closed

refs.form.getValue() should return auto-complete values #102

webmasterkai opened this issue Apr 9, 2015 · 3 comments

Comments

@webmasterkai
Copy link

tcomb-form requires a change event to update its value. Browsers performing an autofill do not always dispatch the change event. The result is a Struct with incomplete or missing property values.

The solutions I'm aware of:

  1. Get the values from the DOM on "submit" or at regular intervals with something like this.refs[field].getDOMNode().value.
  2. Disable autocomplete on the form using autocomplete="off".

Related links:

@gcanti
Copy link
Owner

gcanti commented Apr 9, 2015

Hi!
Thanks for the heads up (great issue, very informative)

It seems a common issue insin/newforms#77

Disable autocomplete on the form using autocomplete="off"

This is easy: #95 (comment)
just add autocomplete="off" to your form tag.

@gcanti
Copy link
Owner

gcanti commented Apr 10, 2015

Another option could be setting the id attributes and read the values later, e.g. in componentDidMount:

var React = require('react');
var t = require('tcomb-form');

window.React = React;

var Form = t.form.Form;

var Type = t.struct({
  username: t.Str,
  password: t.Str
});

var options = {
  fields: {
    username: {
      id: 'username'
    },
    password: {
      id: 'password',
      type: 'password'
    }
  }
};

var App = React.createClass({

  getInitialState: function () {
    return {};
  },

  onChange: function (value) {
    this.setState({value: value});
  },

  componentDidMount: function () {
    var username = document.getElementById('username').value.trim() || null;
    var password = document.getElementById('password').value.trim() || null;
    this.setState({
      value: {
        username: username,
        password: password
      }
    });
  },

  save: function () {
    var value = this.refs.form.getValue();
    if (value) {
      console.log(value);
    }
  },

  render: function() {
    return (
      <div>
        <Form ref="form"
          type={Type}
          options={options}
          onChange={this.onChange}
          value={this.state.value}
        />
        <button className="btn btn-primary" onClick={this.save}>Save</button>
      </div>
    );
  }

});

React.render(<App />, document.getElementById('app'));

@gcanti gcanti closed this as completed May 4, 2015
@dearlordylord
Copy link
Sponsor

To anyone who stuck with is: @gcanti example will work but for some cases won't, without additional changes. Thing is, ios safary have an option to autofill whenever it or user want (with special button in interface), and componentDidMount hack won't work in this case. You should call code that is inside componentDidMount() before this.refs.form.getValue() also, and make sure that this.refs.form.getValue() is called after the state is set, i.e. in setState() callback.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants