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

feat: support error list to show at the top or bottom #3196

Merged
Merged
5 changes: 2 additions & 3 deletions CHANGELOG.md
Expand Up @@ -19,7 +19,8 @@ should change the heading of the (upcoming) version to include a major version b

## @rjsf/chakra-ui
- Automatically close single-choice Select widget on selection

jacqueswho marked this conversation as resolved.
Show resolved Hide resolved
## @rjsf/core
- ShowErrorList prop changed to support `top` or `bottom` [#634](https://github.com/rjsf-team/react-jsonschema-form/issues/634)
jacqueswho marked this conversation as resolved.
Show resolved Hide resolved
# 5.0.0-beta.11

## @rjsf/antd
Expand All @@ -38,15 +39,13 @@ should change the heading of the (upcoming) version to include a major version b
- In `SelectWidget` multiple-choice select display label rather than value for selected items
- Updated `ArrayFieldTemplate` to always render `ArrayFieldDescriptionTemplate` since that template deals with the optional `description`
- Pass the `schema` into the `ArrayFieldDescriptionTemplate`, `ArrayFieldTitleTemplate`, `DescriptionFieldTemplate` and `TitleFieldTemplate`, fixing [#3176](https://github.com/rjsf-team/react-jsonschema-form/issues/3176)

jacqueswho marked this conversation as resolved.
Show resolved Hide resolved
## @rjsf/core
- Extended `Form.onChange` to optionally return the `id` of the field that caused the change, fixing [#2768](https://github.com/rjsf-team/react-jsonschema-form/issues/2768)
- Fixed a regression in earlier v5 beta versions where additional properties could not be added when `additionalProperties` was `true` ([#3719](https://github.com/rjsf-team/react-jsonschema-form/pull/3719)).
- Fixed a regression in v5 beta version where BooleanField was altering readonly props ([#3188](https://github.com/rjsf-team/react-jsonschema-form/pull/3188).
- Updated `ArrayFieldDescriptionTemplate` and `ArrayFieldTitleTemplate` to not render content when `ui:label` is false, fixing [#2535](https://github.com/rjsf-team/react-jsonschema-form/issues/2535)
- Updated `ArrayFieldTemplate` to always render `ArrayFieldDescriptionTemplate` since that template deals with the optional `description`
- Pass the `schema` into the `ArrayFieldDescriptionTemplate`, `ArrayFieldTitleTemplate`, `DescriptionFieldTemplate` and `TitleFieldTemplate`, fixing [#3176](https://github.com/rjsf-team/react-jsonschema-form/issues/3176)

heath-freenome marked this conversation as resolved.
Show resolved Hide resolved
jacqueswho marked this conversation as resolved.
Show resolved Hide resolved
## @rjsf/fluent-ui
- Updated `ArrayFieldTemplate` to always render `ArrayFieldDescriptionTemplate` since that template deals with the optional `description`
- Pass the `schema` into the `ArrayFieldDescriptionTemplate`, `ArrayFieldTitleTemplate`, `DescriptionFieldTemplate` and `TitleFieldTemplate`, fixing [#3176](https://github.com/rjsf-team/react-jsonschema-form/issues/3176)
Expand Down
12 changes: 6 additions & 6 deletions docs/5.x upgrade guide.md
Expand Up @@ -44,15 +44,15 @@ Some of the most notable changes are:

- `RJSFSchema` has replaced the use of `JSON7Schema` for future compatibility reasons.
- Currently `RJSFSchema` is simply an alias to `JSON7Schema` so this change is purely a naming one.
- It is highly recommended to update your use of `JSON7Schema` with `RJSFSchema` so that when the RJSF begins supporting a newer JSON Schema version out-of-the-box, your code won't be affected.
- It is highly recommended to update your use of `JSON7Schema` with `RJSFSchema` so that when the RJSF begins supporting a newer JSON Schema version out-of-the-box, your code won't be affected.
- `RJSFSchemaDefinition` has replaced the use of `JSONSchema7Definition` for the same reasons.
- The use of the generic `T` (defaulting to `any`) for the `formData` type has been expanded to cover all type hierarchies that use `formData`.
- A new generic `F` (defaulting to `any`) was added for the `formContext` type, and all types in the hierarchy that use `formContext` have had that generic added to them.
- The new `CustomValidator`, `ErrorTransformer`, `ValidationData`, `ValidatorType` and `SchemaUtilsType` types were added to support the decoupling of the validation implementation.
- The new `TemplatesType`, `ArrayFieldDescriptionProps`, `ArrayFieldTitleProps`, `UnsupportedFieldProps`, `IconButtonProps`, `SubmitButtonProps` and `UIOptionsBaseType` were added to support the consolidation (and expansion) of `templates` in the `Registry` and `Form`.
- **BREAKING CHANGE** The `DescriptionField` and `TitleField` props were removed from the `ArrayFieldTemplateProps` and `ObjectFieldTemplateProps` as they can now be derived from the `templates` or `uiSchema` via the new `getTemplate()` utility function.
- **BREAKING CHANGE** The `fields` prop was removed from the `FieldTemplateProps` as you can simply use `registry.fields` instead.

- **BREAKING CHANGE** The `showErrorList` prop was changed to accept `false`, `"top"` or `"bottom"`. `true` is no longer a valid value. The default value is `"top"`, which has identical behavior to the default value/`true` in v4.
You can view all these [types](https://github.com/rjsf-team/react-jsonschema-form/blob/main/packages/utils/src/types.ts) on Github.

#### Form props
Expand Down Expand Up @@ -121,7 +121,7 @@ formRef.current.formElement.current.reset();
```

##### `validate` prop renamed
Additionally, in version 5, the `validate` prop on `Form` was renamed to `customValidate` to avoid confusion with the new `validator` prop.
Additionally, in version 5, the `validate` prop on `Form` was renamed to `customValidate` to avoid confusion with the new `validator` prop.

##### `fields` prop changes
In previous versions, it was possible to provide an override to the `DescriptionField`, `TitleField` and/or `UnsupportedField` components by providing a custom implementation in the `fields` prop on the `Form`.
Expand Down Expand Up @@ -252,8 +252,8 @@ function YourWidget(props: WidgetProps) {
const isMultiSelect = schemaUtils.isMultiSelect(schema);
const newSchema: RJSFSchema = schemaUtils.retrieveSchema(schema, formData);
const options = getUiOptions(uiSchema);
...

...
}
```

Expand Down Expand Up @@ -406,7 +406,7 @@ If you are using `classNames` as follows, simply add the `ui:` prefix to it to r
// This uiSchema will log a deprecation warning to the console
const uiSchema = {
title: {
"classNames": "myClass"
"classNames": "myClass"
}
};
// This uiSchema will not
Expand Down
4 changes: 2 additions & 2 deletions docs/api-reference/form-props.md
Expand Up @@ -246,7 +246,7 @@ render((

## showErrorList

When this prop is set to true, a list of errors (or the custom error list defined in the `ErrorList`) will also show. When set to false, only inline input validation errors will be shown. Set to `true` by default. See [Validation](../usage/validation.md) for more information.
When this prop is set to `top` or `bottom`, a list of errors (or the custom error list defined in the `ErrorList`) will also show at the `bottom` or `top` of the form. When set to false, only inline input validation errors will be shown. Set to `top` by default. See [Validation](../usage/validation.md) for more information.

## tagName

Expand Down Expand Up @@ -288,7 +288,7 @@ Form uiSchema. See [uiSchema Reference](uiSchema.md) for more information.

## validator

**Required**! An implementation of the `ValidatorType` interface that is needed for form validation to work.
**Required**! An implementation of the `ValidatorType` interface that is needed for form validation to work.
`@rjsf/validator-ajv6` exports the implementation of this interface from RJSF version 4.

## widgets
Expand Down
12 changes: 6 additions & 6 deletions docs/usage/validation.md
Expand Up @@ -7,7 +7,7 @@ React Json Schema Form provides a default `@rjsf/validator-ajv6` implementation

It also provides a new `@rjsf/validator-ajv8` implementation that uses version 8 of the [ajv](https://github.com/ajv-validator/ajv) validator.
The error messages generated by this new validator differ from those provided by the original validator due to it using a newer version.
If you depend on having specifically formatted messages, then using this validator would constitute a breaking change for you.
If you depend on having specifically formatted messages, then using this validator would constitute a breaking change for you.

It is also possible for you to provide your own implementation if you desire, as long as it fulfills the `ValidatorType` interface specified in `@rjsf/utils`.

Expand Down Expand Up @@ -194,14 +194,14 @@ const schema = {
render((
<Form schema={schema}
validator={validator}
showErrorList={true}
showErrorList='top'
formData={""}
liveValidate
templates: {{ ErrorListTemplate }} />
), document.getElementById("app"));
```

> Note: Your custom `ErrorList` template will only render when `showErrorList` is `true`.
> Note: Your custom `ErrorList` template will only render when `showErrorList` is `top` or `botttom`.

The following props are passed to `ErrorList` as defined by the `ErrorListProps` interface in `@rjsf/utils`:

Expand All @@ -214,7 +214,7 @@ The following props are passed to `ErrorList` as defined by the `ErrorListProps`
## The case of empty strings

When a text input is empty, the field in form data is set to `undefined`.
However, since `undefined` isn't a valid JSON value according to [the official JSON standard](https://www.ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf) (ECMA-404, Section 5), the values get stored as `null`.
However, since `undefined` isn't a valid JSON value according to [the official JSON standard](https://www.ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf) (ECMA-404, Section 5), the values get stored as `null`.

String fields that use `enum` and a `select` widget will have an empty option at the top of the options list that when selected will result in the field being `null`.

Expand Down Expand Up @@ -481,7 +481,7 @@ function localize_ru(errors: null | ErrorObject[] = []) {
if (!(errors && errors.length)) return;
errors.forEach(function(error) {
let outMessage = "";

switch (error.keyword) {
case "pattern": {
outMessage = 'должно соответствовать образцу "' + error.params.pattern + '"';
Expand All @@ -494,7 +494,7 @@ function localize_ru(errors: null | ErrorObject[] = []) {
default:
outMessage = error.message;
}

error.message = outMessage;
})
}
Expand Down
40 changes: 21 additions & 19 deletions packages/core/src/components/Form.tsx
@@ -1,34 +1,34 @@
import React, { Component } from "react";
import {
heath-freenome marked this conversation as resolved.
Show resolved Hide resolved
createSchemaUtils,
CustomValidator,
deepEquals,
ErrorSchema,
ErrorTransformer,
GenericObjectType,
getTemplate,
getUiOptions,
IdSchema,
isObject,
mergeObjects,
NAME_KEY,
PathSchema,
RJSFSchema,
RJSFValidationError,
Registry,
RegistryWidgetsType,
RegistryFieldsType,
RegistryWidgetsType,
RJSFSchema,
RJSFValidationError,
RJSF_ADDITONAL_PROPERTIES_FLAG,
SchemaUtilsType,
shouldRender,
TemplatesType,
UiSchema,
ValidationData,
ValidatorType,
createSchemaUtils,
deepEquals,
getTemplate,
getUiOptions,
isObject,
mergeObjects,
shouldRender,
NAME_KEY,
RJSF_ADDITONAL_PROPERTIES_FLAG,
} from "@rjsf/utils";
import _pick from "lodash/pick";
import _get from "lodash/get";
import _isEmpty from "lodash/isEmpty";
import _pick from "lodash/pick";

import getDefaultRegistry from "../getDefaultRegistry";

Expand Down Expand Up @@ -156,10 +156,10 @@ export interface FormProps<T = any, F = any> {
* called. Set to `false` by default.
*/
omitExtraData?: boolean;
/** When this prop is set to true, a list of errors (or the custom error list defined in the `ErrorList`) will also
* show. When set to false, only inline input validation errors will be shown. Set to `true` by default
/** When this prop is set to `top` or 'bottom', a list of errors (or the custom error list defined in the `ErrorList`) will also
* show. When set to false, only inline input validation errors will be shown. Set to `top` by default
*/
showErrorList?: boolean;
showErrorList?: false | "top" | "bottom";
/** A function can be passed to this prop in order to make modifications to the default errors resulting from JSON
* Schema validation
*/
Expand Down Expand Up @@ -413,15 +413,15 @@ export default class Form<T = any, F = any> extends Component<
/** Renders any errors contained in the `state` in using the `ErrorList`, if not disabled by `showErrorList`. */
renderErrors(registry: Registry<T, F>) {
const { errors, errorSchema, schema, uiSchema } = this.state;
const { showErrorList, formContext } = this.props;
const { formContext } = this.props;
const options = getUiOptions<T, F>(uiSchema);
const ErrorListTemplate = getTemplate<"ErrorListTemplate", T, F>(
"ErrorListTemplate",
registry,
options
);

if (errors && errors.length && showErrorList != false) {
if (errors && errors.length) {
return (
<ErrorListTemplate
errors={errors}
Expand Down Expand Up @@ -761,6 +761,7 @@ export default class Form<T = any, F = any> extends Component<
disabled = false,
readonly = false,
formContext,
showErrorList = "top",
_internalFormWrapper,
} = this.props;

Expand Down Expand Up @@ -790,7 +791,7 @@ export default class Form<T = any, F = any> extends Component<
as={as}
ref={this.formElement}
>
{this.renderErrors(registry)}
{showErrorList === "top" && this.renderErrors(registry)}
<_SchemaField
name=""
schema={schema}
Expand All @@ -809,6 +810,7 @@ export default class Form<T = any, F = any> extends Component<
readonly={readonly}
/>
{children ? children : <SubmitButton uiSchema={uiSchema} />}
{showErrorList === "bottom" && this.renderErrors(registry)}
</FormTag>
);
}
Expand Down
1 change: 1 addition & 0 deletions packages/playground/src/app.jsx
Expand Up @@ -21,6 +21,7 @@ const liveSettingsSchema = {
omitExtraData: { type: "boolean", title: "Omit extra data" },
liveOmit: { type: "boolean", title: "Live omit" },
noValidate: { type: "boolean", title: "Disable validation" },
showErrorList:{ type: "string", "default":"top", title: "Show Error List", enum:[false,"top","bottom"] }
},
};

Expand Down