Skip to content

Commit 8654a61

Browse files
Properly pass formContext to SchemaField
- Updated `ArrayField`, `MultiSchemaField`, `ObjectField` and `SchemaField` to pass `formContext` down the hierarchy properly - Updated tests to validate `formContext` is properly passed to `SchemaField` - Updated the `CHANGELOG.md` file with the fix mentioned
1 parent 1c46492 commit 8654a61

File tree

9 files changed

+156
-0
lines changed

9 files changed

+156
-0
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ should change the heading of the (upcoming) version to include a major version b
2323
- **BREAKING CHANGE** Fix overriding core submit button className (https://github.com/rjsf-team/react-jsonschema-form/issues/2979)
2424
- Fix `ui:field` with anyOf or oneOf no longer rendered twice (#2890)
2525
- **BREAKING CHANGE** Fixed `anyOf` and `oneOf` getting incorrect, potentially duplicate ids when combined with array (https://github.com/rjsf-team/react-jsonschema-form/issues/2197)
26+
- `formContext` is now passed properly to `SchemaField`, fixes (https://github.com/rjsf-team/react-jsonschema-form/issues/2394, https://github.com/rjsf-team/react-jsonschema-form/issues/2274)
2627

2728
## @rjsf/semantic-ui
2829
- Fix missing error class on fields (https://github.com/rjsf-team/react-jsonschema-form/issues/2666)

packages/core/src/components/fields/ArrayField.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,7 @@ class ArrayField<T = any, F = any> extends Component<
802802
readonly,
803803
uiSchema,
804804
registry,
805+
formContext,
805806
} = this.props;
806807
const {
807808
fields: { SchemaField },
@@ -825,6 +826,7 @@ class ArrayField<T = any, F = any> extends Component<
825826
schema={itemSchema}
826827
uiSchema={itemUiSchema}
827828
formData={itemData}
829+
formContext={formContext}
828830
errorSchema={itemErrorSchema}
829831
idPrefix={idPrefix}
830832
idSeparator={idSeparator}

packages/core/src/components/fields/MultiSchemaField.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ class AnyOfField<T = any, F = any> extends Component<
151151
hideError = false,
152152
errorSchema = {},
153153
formData,
154+
formContext,
154155
idPrefix,
155156
idSeparator,
156157
idSchema,
@@ -199,6 +200,7 @@ class AnyOfField<T = any, F = any> extends Component<
199200
value={selectedOption}
200201
options={{ enumOptions }}
201202
registry={registry}
203+
formContext={formContext}
202204
{...uiOptions}
203205
label=""
204206
/>
@@ -213,6 +215,7 @@ class AnyOfField<T = any, F = any> extends Component<
213215
idPrefix={idPrefix}
214216
idSeparator={idSeparator}
215217
formData={formData}
218+
formContext={formContext}
216219
onChange={onChange}
217220
onBlur={onBlur}
218221
onFocus={onFocus}

packages/core/src/components/fields/ObjectField.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ class ObjectField<T = any, F = any> extends Component<
286286
idPrefix={idPrefix}
287287
idSeparator={idSeparator}
288288
formData={get(formData, name)}
289+
formContext={formContext}
289290
wasPropertyKeyModified={this.state.wasPropertyKeyModified}
290291
onKeyChange={this.onKeyChange(name)}
291292
onChange={this.onPropertyChange(

packages/core/src/components/fields/SchemaField.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ function SchemaFieldRender<T, F>(props: FieldProps<T, F>) {
313313
hideError={hideError}
314314
errorSchema={errorSchema}
315315
formData={formData}
316+
formContext={formContext}
316317
idPrefix={idPrefix}
317318
idSchema={idSchema}
318319
idSeparator={idSeparator}
@@ -341,6 +342,7 @@ function SchemaFieldRender<T, F>(props: FieldProps<T, F>) {
341342
hideError={hideError}
342343
errorSchema={errorSchema}
343344
formData={formData}
345+
formContext={formContext}
344346
idPrefix={idPrefix}
345347
idSchema={idSchema}
346348
idSeparator={idSeparator}

packages/core/test/ArrayField_test.js

+43
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Simulate } from "react-dom/test-utils";
55
import sinon from "sinon";
66

77
import { createFormComponent, createSandbox, submitForm } from "./test_utils";
8+
import SchemaField from "../src/components/fields/SchemaField";
89

910
const ArrayKeyDataAttr = "data-rjsf-itemkey";
1011
const ExposedArrayKeyTemplate = function (props) {
@@ -2177,4 +2178,46 @@ describe("ArrayField", () => {
21772178
expect(inputsNoError).to.have.length.of(0);
21782179
});
21792180
});
2181+
describe("FormContext gets passed", () => {
2182+
const schema = {
2183+
type: "array",
2184+
items: [
2185+
{
2186+
type: "string",
2187+
title: "Some text",
2188+
},
2189+
{
2190+
type: "number",
2191+
title: "A number",
2192+
},
2193+
],
2194+
};
2195+
it("should pass form context to schema field", () => {
2196+
const formContext = {
2197+
root: "root-id",
2198+
root_0: "root_0-id",
2199+
root_1: "root_1-id",
2200+
};
2201+
function CustomSchemaField(props) {
2202+
const { formContext, idSchema } = props;
2203+
return (
2204+
<>
2205+
<code id={formContext[idSchema.$id]}>Ha</code>
2206+
<SchemaField {...props} />
2207+
</>
2208+
);
2209+
}
2210+
const { node } = createFormComponent({
2211+
schema,
2212+
formContext,
2213+
fields: { SchemaField: CustomSchemaField },
2214+
});
2215+
2216+
const codeBlocks = node.querySelectorAll("code");
2217+
expect(codeBlocks).to.have.length(3);
2218+
Object.keys(formContext).forEach((key) => {
2219+
expect(node.querySelector(`code#${formContext[key]}`)).to.exist;
2220+
});
2221+
});
2222+
});
21802223
});

packages/core/test/ObjectField_test.js

+29
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { expect } from "chai";
33
import { Simulate } from "react-dom/test-utils";
44
import sinon from "sinon";
55

6+
import SchemaField from "../src/components/fields/SchemaField";
67
import { createFormComponent, createSandbox, submitForm } from "./test_utils";
78

89
describe("ObjectField", () => {
@@ -190,6 +191,34 @@ describe("ObjectField", () => {
190191
expect(node.querySelector("input[type=text]").id).eql("root_foo");
191192
expect(node.querySelector("input[type=checkbox]").id).eql("root_bar");
192193
});
194+
195+
it("should pass form context to schema field", () => {
196+
const formContext = {
197+
root: "root-id",
198+
root_foo: "foo-id",
199+
root_bar: "bar-id",
200+
};
201+
function CustomSchemaField(props) {
202+
const { formContext, idSchema } = props;
203+
return (
204+
<>
205+
<code id={formContext[idSchema.$id]}>Ha</code>
206+
<SchemaField {...props} />
207+
</>
208+
);
209+
}
210+
const { node } = createFormComponent({
211+
schema,
212+
formContext,
213+
fields: { SchemaField: CustomSchemaField },
214+
});
215+
216+
const codeBlocks = node.querySelectorAll("code");
217+
expect(codeBlocks).to.have.length(3);
218+
Object.keys(formContext).forEach((key) => {
219+
expect(node.querySelector(`code#${formContext[key]}`)).to.exist;
220+
});
221+
});
193222
});
194223

195224
describe("fields ordering", () => {

packages/core/test/allOf_test.js

+34
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { expect } from "chai";
22

33
import { createFormComponent, createSandbox } from "./test_utils";
4+
import SchemaField from "../src/components/fields/SchemaField";
5+
import React from "react";
46

57
describe("allOf", () => {
68
let sandbox;
@@ -46,4 +48,36 @@ describe("allOf", () => {
4648

4749
expect(node.querySelectorAll("input")).to.have.length.of(0);
4850
});
51+
it("should pass form context to schema field", () => {
52+
const schema = {
53+
type: "object",
54+
properties: {
55+
foo: {
56+
allOf: [{ type: "string" }, { type: "boolean" }],
57+
},
58+
},
59+
};
60+
const formContext = { root: "root-id", root_foo: "foo-id" };
61+
function CustomSchemaField(props) {
62+
const { formContext, idSchema } = props;
63+
return (
64+
<>
65+
<code id={formContext[idSchema.$id]}>Ha</code>
66+
<SchemaField {...props} />
67+
</>
68+
);
69+
}
70+
const { node } = createFormComponent({
71+
schema,
72+
formData: { userId: "foobarbaz" },
73+
formContext,
74+
fields: { SchemaField: CustomSchemaField },
75+
});
76+
77+
const codeBlocks = node.querySelectorAll("code");
78+
expect(codeBlocks).to.have.length(2);
79+
Object.keys(formContext).forEach((key) => {
80+
expect(node.querySelector(`code#${formContext[key]}`)).to.exist;
81+
});
82+
});
4983
});

packages/core/test/oneOf_test.js

+41
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Simulate } from "react-dom/test-utils";
44
import sinon from "sinon";
55

66
import { createFormComponent, createSandbox, setProps } from "./test_utils";
7+
import SchemaField from "../src/components/fields/SchemaField";
78

89
describe("oneOf", () => {
910
let sandbox;
@@ -394,6 +395,46 @@ describe("oneOf", () => {
394395
expect(node.querySelectorAll("#custom-oneof-field")).to.have.length(1);
395396
});
396397

398+
it("should pass form context to schema field", () => {
399+
const schema = {
400+
type: "object",
401+
properties: {
402+
userId: {
403+
oneOf: [
404+
{
405+
type: "number",
406+
},
407+
{
408+
type: "string",
409+
},
410+
],
411+
},
412+
},
413+
};
414+
const formContext = { root: "root-id", root_userId: "userId-id" };
415+
function CustomSchemaField(props) {
416+
const { formContext, idSchema } = props;
417+
return (
418+
<>
419+
<code id={formContext[idSchema.$id]}>Ha</code>
420+
<SchemaField {...props} />
421+
</>
422+
);
423+
}
424+
const { node } = createFormComponent({
425+
schema,
426+
formData: { userId: "foobarbaz" },
427+
formContext,
428+
fields: { SchemaField: CustomSchemaField },
429+
});
430+
431+
const codeBlocks = node.querySelectorAll("code");
432+
expect(codeBlocks).to.have.length(3);
433+
Object.keys(formContext).forEach((key) => {
434+
expect(node.querySelector(`code#${formContext[key]}`)).to.exist;
435+
});
436+
});
437+
397438
it("should select the correct field when the form is rendered from existing data", () => {
398439
const schema = {
399440
type: "object",

0 commit comments

Comments
 (0)