1
votes

I'm trying to display an error in a form field by adding a className. This is the render function:

render() {
  return (
    <div className="row row--no-margin">
      <button onClick={this.validate}>Test validation</button>
      {
        this.props.model.map( (field, index) => {
          return this.renderTextField(field);
        });
      }
    </div>
  );
}

This is the renderTextField function:

renderTextField(field, index) {

  let inputClassNames = 'form-control';
  if (this.state.errors.indexOf(field.name) !== -1) {
    inputClassNames += ' error-required';
  }

  return (
    <div className={field.wrapperClassName} key={field.key}>
      <label className="field-label">{field.label}</label>
      <input 
        type="text"
        name={field.name} 
        ref={field.name}
        className={inputClassNames} 
        onChange={this.handleChange}
        value={this.state[field.name]}
      />
    </div>
  ); 
}

When i click the button to test validation, the class "error-required" is added to the input, but as soon as i type anything, it loses the class.

This is the onChange function:

handleChange(event) {
  this.setState({
    [event.target.name] : event.target.value
  });
}

The field gets its data from an object:

{ key : 'name', name : 'name', type : 'text', label : 'Full Name', wrapperClassName: 'col-md-6', },

Am i missing something?

EDIT:

validate function:

validate() {

  let errors = [];

  this.props.model.map((m, index) => {
    if(!this.state[m.name]){
      errors.push(m.name);
    }
  });

  this.setState({
    errors: errors
  })
}
1
can you please add the code for validate() ?Dacre Denny
I edited the question with validate(), thank you.rnantes
In your renderTextField function, try changing onChange={this.handleChange} to onChange={()=>this.handleChange}.Adam

1 Answers

0
votes

I would suggest separating the form's "field state", from your "validation state", to avoid potential conflicts in the case that you have a field with name "error".

If your form has a field with name "error", changing it's value will cause your validation state to be replaced, and will produce errors/unexpected results.

Consider making the following adjustments:

// in renderTextField() use this.state.form[field.name]

<input 
  type="text"
  name={field.name} 
  ref={field.name}
  className={inputClassNames} 
  onChange={this.handleChange}
  value={this.state.form[field.name]} 
  />

And in handleChange(event) consider revising it to:

handleChange(event) {

const form = { ...this.state.form, [event.target.name] : event.target.value }

this.setState({
  form : form
})
}

Note, you will also need to initialise your component state to include/define the form object to track the state of fields.