Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example for modifying the style of the input based on validation #23

Closed
ryanhyslop opened this issue Apr 26, 2018 · 2 comments
Closed

Comments

@ryanhyslop
Copy link

Hi, firstly really like the look of this library and seriously considering using it in a project so thanks!

I was curious as to whether you had considered a means to modify the styling of the actual input when its invalid? A common pattern would be to change the colour of the border or background for instance.

I notice (at least as far as v.0.7) the fieldStore keeps a reference to all the fields and theres an error property on them. It wouldn't be too difficult to read from this to check if a field has an error;

ie.form.fieldsStore.fields.fieldName.errors

but was wary of using something thats not an official API for this. Something akin to:
className: (form.fieldStore.isFieldValid('name')) ? 'is-valid' : ' is-not-valid';

@tkrotoff
Copy link
Owner

Good question!

I've just released v0.8.0. Took me a lot of time because it's a full rewrite (multiple rewrites actually, to find the good recipe). A few things have changed since v0.7.0.

I do change the input border color for Bootstrap with react-form-with-constraints-bootstrap4, example: https://github.com/tkrotoff/react-form-with-constraints/blob/v0.8.0/examples/Bootstrap4/App.jsx#L88

FormInput implementation is here: https://github.com/tkrotoff/react-form-with-constraints/blob/v0.8.0/packages/react-form-with-constraints-bootstrap4/src/Bootstrap.tsx#L19

You have 2 events: FieldWillValidate and FieldDidValidate, then you change the state based on them (and then change the input className or whatever).

getInputBorderColor(fieldName: string) {
  let color = undefined;
  if (this.form !== null) { // On first render, this.form is null
    const field = this.form.fieldsStore.getField(fieldName);
    if (field.hasAnyFeedbacks()) { // More or less tells if the field is dirty (e.g. has been touched by the user)
      color = field.isValid() ? 'green' : 'red';
    }
  }
  return color;
}

// ...

<FormWithConstraints ref={formWithConstraints => this.form = formWithConstraints}
                     onSubmit={this.handleSubmit} noValidate>
  <input type="email" name="username" id="username"
         value={this.state.username} onChange={this.handleChange}
         required minLength={5}
         style={{borderWidth: '1em', borderColor: this.getInputBorderColor('username')}}
  />

  <input type="password" name="password" id="password"
         ref={password => this.password = password}
         value={this.state.password} onChange={this.handlePasswordChange}
         required pattern=".{5,}"
         style={{borderWidth: '1em', borderColor: this.getInputBorderColor('password')}}
  />
</FormWithConstraints>

It works because there is a re-render each time an input is changed (this.state.username)

  • There is another approach by playing with FormWithConstraints.validateFields():
const field = await this.form.validateFields(myField); // "field" being identical to "const field = this.form.fieldsStore.getField(...)"
this.setState({myFieldIsValid: field.isValid()});

Why not move FormInput from react-form-with-constraints-bootstrap4 to react-form-with-constraints.
Also isValid() is confusing because it does not check if the field is dirty.

@ryanhyslop
Copy link
Author

Brilliant thanks, I went with a custom variation of your bootstrap example!

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

No branches or pull requests

2 participants