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

Validate onBlur? #617

Closed
1 task done
infin1t3 opened this issue Jun 20, 2017 · 15 comments
Closed
1 task done

Validate onBlur? #617

infin1t3 opened this issue Jun 20, 2017 · 15 comments

Comments

@infin1t3
Copy link

infin1t3 commented Jun 20, 2017

Prerequisites

Description

Is it possible to validate a field on Blur event? I would like to do that for, for example, email input.

@eddyzhang1986
Copy link

I have the same question.

@infin1t3
Copy link
Author

infin1t3 commented Jul 5, 2017

@eddyzhang1986 Its not possible to do so. I recommend you to create your own implementation of jsonschema generator, its not hard and you ll have all flexibility you need.

@knilink
Copy link
Contributor

knilink commented Jul 7, 2017

A demo of OO solution for validate onBlur for the whole form.

import Form from 'react-jsonschema-form';
class BlurForm extends Form {
  constructor(props) {
    super(props);
    const superOnBlur = this.onBlur;
    this.onBlur = (...args) => {
      const { formData } = this.state;
      const { errors, errorSchema } = this.validate(formData);
      this.setState({ errors, errorSchema },()=>superOnBlur(...args));
    }
  }
}

The rest is the same, just don't enable live validation.

My experience was that the on blur is unreliable. The on blur event came after the on click which mean if users click submit in the middle of editing a field, it fnck up.

@MrOrz
Copy link

MrOrz commented Jul 7, 2017

@knilink thanks for the code snippet! It works like a charm.

In my scenario I blocks form submission and force the users to fix their input before submit. Validating when blur event is fired would help users visualizing their progress in fixing inputs.

I agree that on blur is unreliable. Therefore, I would like to validate both on submit and on blur, to strike a balance between user experience and reliability.

@infin1t3 infin1t3 closed this as completed Aug 4, 2017
@altaywtf
Copy link

@knilink thanks for the snippet! but it validates all fields (even the untouched ones) when blur event is triggered. Is it possible to perform onBlur validation per field?

@glasserc
Copy link
Contributor

At present, react-jsonschema-form doesn't attempt to validate any user input at anything less than "the entire form" level.

@MichaelWashburnJr
Copy link

MichaelWashburnJr commented Feb 7, 2018

Why was this closed? This should be kept open and a prop should be added to the <Form> so that this feature can be toggled, just like liveValidate. Validating on blur is a very common case.

@lewisl9029
Copy link

lewisl9029 commented Aug 20, 2019

I was able to implement this using a combination of liveValidate on the form and a few higher order components to manually track blurred state and show errors only once a field has been blurred on my custom widgets.

Here's what that could look like:

import {
  compose,
  mapProps,
  withStateHandlers,
} from "recompose";

const rawErrorsToErrorMessage = mapProps(
  ({ rawErrors, isBlurred, ...props }) => ({
    ...props,
    // TODO: Also need to show all errors after first submit
    errorMessage: isBlurred && rawErrors && (
      <React.Fragment>
        {rawErrors.map((error) => (
          <div>{error}</div>
        ))}
      </React.Fragment>
    ),
  }),
);

const withBlurred = withStateHandlers(
  { isBlurred: false },
  {
    onBlur: () => () => ({
      isBlurred: true,
    }),
  },
);

const transformWidgetProps = compose(
  withBlurred,
  rawErrorsToErrorMessage,
);

const widgets: any = {
  text: transformWidgetProps(TextInput),
  select: transformWidgetProps(OptionInput),
};

Hope this could be useful to others here.

UPDATE: Never mind, I later ran into a brick wall trying to show errors after the first submit attempt by wrapping a state tracking HOC around the form. For some reason, when the form gets rerendered, inputs lose their focus.

@KKS1
Copy link

KKS1 commented Jan 10, 2020

Create an example for selective field level onBlur validation.
https://codesandbox.io/s/blur-validation-react-json-schema-form-txnk8
Just provide 'validateOnBlur' true, in the uiSchema for that field, and it will do the job.

Hope it helps anyone facing this issue !

@jedmonsanto
Copy link

hope this help issue: 431

@stvhanna
Copy link

stvhanna commented Sep 15, 2020

@KKS1 Thank you for putting together a proof of concept! I'm trying to get your example to work with material-ui and running into a problem. Since you're extending the Form, it requires:
import Form from '@rjsf/core';

and when I try this:

import { withTheme } from '@rjsf/core';
import { Theme as MaterialUITheme } from '@rjsf/material-ui';
const Form = withTheme(MaterialUITheme);

I get an error Uncaught TypeError: Class extends value #<Object> is not a constructor or null

How do I get onblur validation to work with Material UI? Any help would be greatly appreciated.

@epicfaace
Copy link
Member

Did it work with import Form from '@rjsf/material-ui';

@stvhanna
Copy link

@epicfaace No, same error.

@KKS1
Copy link

KKS1 commented Sep 19, 2020

@stvhanna Created an end-to-end Material UI based implementation, using function based approach.
https://codesandbox.io/s/material-ui-blur-validation-react-json-schema-form-j4bms

Of-course, we can further optimize it using one time run effect, which can then call referenced Form onBlur if needed.
But this will give you ( or anyone else facing this issue) a base to start working with and make it production ready.

Hope it helps, cheers!

@zmagauina-fn
Copy link
Contributor

This is stale but I thought I'd share my approach for anyone still looking. I expanded one of the previous implementations, here's a simplified version of my solution:
https://codesandbox.io/s/material-ui-blur-validation-react-json-schema-form-forked-kmxtd

I turned off the form validation and kept the errors in the state myself, passing them to the form through the extraErrors prop. It also works with nested objects.

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