Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/components/fields/ArrayField.js
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ class ArrayField extends Component {
onBlur,
onFocus,
idPrefix,
rawErrors,
} = this.props;
const title = schema.title === undefined ? name : schema.title;
const { ArrayFieldTemplate, definitions, fields, formContext } = registry;
Expand Down Expand Up @@ -411,6 +412,7 @@ class ArrayField extends Component {
TitleField,
formContext,
formData,
rawErrors,
};

// Check if a custom render function was passed in
Expand All @@ -430,6 +432,7 @@ class ArrayField extends Component {
onBlur,
onFocus,
registry = getDefaultRegistry(),
rawErrors,
} = this.props;
const items = this.props.formData;
const { widgets, definitions, formContext } = registry;
Expand All @@ -454,6 +457,7 @@ class ArrayField extends Component {
readonly={readonly}
formContext={formContext}
autofocus={autofocus}
rawErrors={rawErrors}
/>
);
}
Expand All @@ -470,6 +474,7 @@ class ArrayField extends Component {
onBlur,
onFocus,
registry = getDefaultRegistry(),
rawErrors,
} = this.props;
const title = schema.title || name;
const items = this.props.formData;
Expand All @@ -491,6 +496,7 @@ class ArrayField extends Component {
readonly={readonly}
formContext={formContext}
autofocus={autofocus}
rawErrors={rawErrors}
/>
);
}
Expand All @@ -511,6 +517,7 @@ class ArrayField extends Component {
registry = getDefaultRegistry(),
onBlur,
onFocus,
rawErrors,
} = this.props;
const title = schema.title || name;
let items = this.props.formData;
Expand Down Expand Up @@ -579,6 +586,7 @@ class ArrayField extends Component {
title,
TitleField,
formContext,
rawErrors,
};

// Check if a custom template template was passed in
Expand All @@ -600,6 +608,7 @@ class ArrayField extends Component {
autofocus,
onBlur,
onFocus,
rawErrors,
} = props;
const {
disabled,
Expand Down Expand Up @@ -636,6 +645,7 @@ class ArrayField extends Component {
disabled={this.props.disabled}
readonly={this.props.readonly}
autofocus={autofocus}
rawErrors={rawErrors}
/>
),
className: "array-item",
Expand Down
145 changes: 144 additions & 1 deletion test/ArrayField_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import { createFormComponent, createSandbox } from "./test_utils";

describe("ArrayField", () => {
let sandbox;
const CustomComponent = () => <div id="custom" />;
const CustomComponent = props => {
return <div id="custom">{props.rawErrors}</div>;
};

beforeEach(() => {
sandbox = createSandbox();
Expand Down Expand Up @@ -98,6 +100,29 @@ describe("ArrayField", () => {
expect(node.querySelector("#custom")).to.exist;
});

it("should pass rawErrors down to custom array field templates", () => {
const schema = {
type: "array",
title: "my list",
description: "my description",
items: { type: "string" },
minItems: 2,
};

const { node } = createFormComponent({
schema,
ArrayFieldTemplate: CustomComponent,
formData: [1],
liveValidate: true,
});

const matches = node.querySelectorAll("#custom");
expect(matches).to.have.length.of(1);
expect(matches[0].textContent).to.eql(
"should NOT have less than 2 items"
);
});

it("should contain no field in the list by default", () => {
const { node } = createFormComponent({ schema });

Expand Down Expand Up @@ -660,6 +685,23 @@ describe("ArrayField", () => {

expect(node.querySelector("select").id).eql("root");
});

it("should pass rawErrors down to custom widgets", () => {
const { node } = createFormComponent({
schema,
widgets: {
SelectWidget: CustomComponent,
},
formData: ["foo", "foo"],
liveValidate: true,
});

const matches = node.querySelectorAll("#custom");
expect(matches).to.have.length.of(1);
expect(matches[0].textContent).to.eql(
"should NOT have duplicate items (items ## 0 and 1 are identical)"
);
});
});

describe("CheckboxesWidget", () => {
Expand Down Expand Up @@ -729,6 +771,35 @@ describe("ArrayField", () => {

expect(node.querySelectorAll(".checkbox-inline")).to.have.length.of(3);
});

it("should pass rawErrors down to custom widgets", () => {
const schema = {
type: "array",
title: "My field",
items: {
enum: ["foo", "bar", "fuzz"],
type: "string",
},
minItems: 3,
uniqueItems: true,
};

const { node } = createFormComponent({
schema,
widgets: {
CheckboxesWidget: CustomComponent,
},
uiSchema,
formData: [],
liveValidate: true,
});

const matches = node.querySelectorAll("#custom");
expect(matches).to.have.length.of(1);
expect(matches[0].textContent).to.eql(
"should NOT have less than 3 items"
);
});
});
});

Expand Down Expand Up @@ -809,6 +880,33 @@ describe("ArrayField", () => {

expect(node.querySelector("input[type=file]").id).eql("root");
});

it("should pass rawErrors down to custom widgets", () => {
const schema = {
type: "array",
title: "My field",
items: {
type: "string",
format: "data-url",
},
minItems: 5,
};

const { node } = createFormComponent({
schema,
widgets: {
FileWidget: CustomComponent,
},
formData: [],
liveValidate: true,
});

const matches = node.querySelectorAll("#custom");
expect(matches).to.have.length.of(1);
expect(matches[0].textContent).to.eql(
"should NOT have less than 5 items"
);
});
});

describe("Nested lists", () => {
Expand Down Expand Up @@ -840,6 +938,51 @@ describe("ArrayField", () => {

expect(node.querySelectorAll("fieldset fieldset")).to.have.length.of(1);
});

it("should pass rawErrors down to every level of custom widgets", () => {
const CustomItem = props => <div id="custom-item">{props.children}</div>;
const CustomTemplate = props => {
return (
<div id="custom">
{props.items &&
props.items.map((p, i) => <CustomItem key={i} {...p} />)}
<div id="custom-error">
{props.rawErrors && props.rawErrors.join(", ")}
</div>
</div>
);
};

const schema = {
type: "array",
title: "A list of arrays",
items: {
type: "array",
title: "A list of numbers",
items: {
type: "number",
},
minItems: 3,
},
minItems: 2,
};

const { node } = createFormComponent({
schema,
ArrayFieldTemplate: CustomTemplate,
formData: [[]],
liveValidate: true,
});

const matches = node.querySelectorAll("#custom-error");
expect(matches).to.have.length.of(2);
expect(matches[0].textContent).to.eql(
"should NOT have less than 3 items"
);
expect(matches[1].textContent).to.eql(
"should NOT have less than 2 items"
);
});
});

describe("Fixed items lists", () => {
Expand Down