8000 Display validation errors in JSON schema form on change/blur of form fields by kuosandys · Pull Request #4059 · giantswarm/happa · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Display validation errors in JSON schema form on change/blur of form fields #4059

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

Merged
merged 22 commits into from
Feb 7, 2023

Conversation

kuosandys
Copy link
Contributor
@kuosandys kuosandys commented Feb 1, 2023

What does this PR do?

This PR enables the display of form validation errors for individual fields on change / on blur.

Changes

When a field is changed or blurred, any validation errors for the field are displayed:
Screenshot 2023-02-01 at 20 49 07
Screenshot 2023-02-01 at 20 49 20

An accordion field in a collapsed state displays a warning icon if any of its child fields contain an error:
Screenshot 2023-02-02 at 15 08 37

The warning icon is only displayed at the deepest layer:
Screenshot 2023-02-02 at 15 08 30

Newly added array items will not display any applicable errors until the item is changed or blurred. For example,arrayOfStrings No. 2 displays an error after having been modified by the user, while arrayOfStrings No. 3 has not been modified by the user, and thus does not display any errors.
Screenshot 2023-02-02 at 15 09 37

How it works

As validating individual fields is not supported out of the box by the library (discussion in rjsf-team/react-jsonschema-form#512) , we implement this by:

  • keeping track of a list of IDs for input fields that the user has blurred/changed
  • displaying any errors for a field if it is in the list of "touched" field IDs
  • when the submit button is clicked, we display all errors, regardless of whether they have been touched by the user
  • we do some shuffling when reordering/dropping array list items

Instead of transforming errors in the form state (possible by passing a function via the transformErrors prop to <Form />), we show/hide errors on the display side (i.e. in the <FieldTemplate /> and <ErrorList />). This is because we need to maintain the capability of validating the entire form on submit.

Background

giantswarm/roadmap#1181

@kuosandys kuosandys marked this pull request as ready for review February 2, 2023 14:23
@kuosandys kuosandys requested a review from a team February 2, 2023 14:23
@kuosandys kuosandys changed the title Form validation errors Display validation errors in JSON schema form on change/blur of form fields Feb 3, 2023
Copy link
Contributor
@gusevda gusevda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

@kuosandys kuosandys merged commit 846c3cf into main Feb 7, 2023
@kuosandys kuosandys deleted the form-validation-errors branch February 7, 2023 13:21
@burks10
Copy link
burks10 commented Jul 5, 2023

@kuosandys is there any docs I can refer to in order to work this into my code?

I currently want to inccorporate this into a custom field I created. I tried to hack my way around this by just setting a boolean flag to bypass validation, but now it bypasses validation on submit :D

class FirstNameField extends React.Component<FieldProps> {
    hasHadFocus = false;
    state = {
        firstName: ''
    }

    constructor(props: FieldProps) {
        super(props);
        this.state = {
            ...{
                firstName: ''
            }
        }
    }

    hasError() {
        if (this.hasHadFocus && this.props.errorSchema.firstName !== undefined) {
            if (this.props.errorSchema.firstName.__errors.length > 0) {
                return true
            }
        }
        return false
    }

    getError() {
        if (this.hasError()) {
            return this.props.errorSchema.firstName.__errors[0];
        }
        return ""
    }

    bluryChange(event) {
        this.hasHadFocus = true
        this.setState(
            {
                firstName: event.target.value,
            },
            () => {
                this.props.onChange(this.state, this.props.errorSchema)
            }
        );
    }

    render() {
        return (
            <TextField
                error={this.hasError()}
                helperText={this.getError()}
                id={this.props.uiSchema['ui:field'] + '-textfield'}
                label={i18n.t('T_first_name')}
               
8000
 variant="outlined"
                value={this.state.firstName}
                required={(this.props.schema.required as string[]).includes('firstName')}
                onBlur={(event) => {
                    console.log(this.props)
                    this.bluryChange(event)
                }}
                onChange={(event) => {
                    this.bluryChange(event)
                }} />
        )
    }
}

export { FirstNameFieldDeclarationType, FirstNameFieldDeclaration, FirstNameField }

@kuosandys
Copy link
Contributor Author

Hey @burks10, I found the discussion in the original react-jsonschema-form issue to be quite helpful, it’s linked in the PR comment above. Unfortunately I don’t have more docs to point you to besides the official ones, but I’ll try to explain what I did here.

In my implementation, I kept track of a list of “touched”/focused on fields in the parent component. On the child component level, I simply hid the error from display if it has not been touched. This should not affect validation submission behaviour as we’re not transforming the errors in the form state. Once the submit button is clicked, all errors are displayed regardless of whether they’ve been touched.

Hope this is helpful, let me know if I could clarify anything

@burks10
Copy link
burks10 commented Jul 6, 2023

Thanks so much for the explanation @kuosandys that's definetley the approach I will take!

However for some reason my Form's onBlur handler on the Form is not firing at all, am I missing something or is this a potential bug?

These are the versions I am on:

        "@rjsf/core": "^5.8.1",
        "@rjsf/mui": "^5.8.1",
        "@rjsf/utils": "^5.8.1",
        "@rjsf/validator-ajv8": "^5.8.1",
<Form
        schema={stores.fieldStore.getKeyedSchemas()}
        uiSchema={stores.fieldStore.getUiSchemas()}
        validator={validator}
        onBlur={(id, data) => {
            console.log('blur');
        }}
        fields={this.fieldRegistrations}
        noHtml5Validate
        liveValidate
        >
</Form>

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

Successfully merging this pull request may close these issues.

3 participants
0