Skip to content

Commit

Permalink
use select widget to render oneOf / anyOf control (#1220)
Browse files Browse the repository at this point in the history
* use select widget to render oneOf / anyOf control

* pass more props to widget

* change schema type to number
* get uiOptions to pass to widget

* do not pass props to custom widget in test

* update tests to actually pass custom widget
  • Loading branch information
a-b-r-o-w-n authored and epicfaace committed Apr 5, 2019
1 parent 73b1458 commit f8d0d45
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 15 deletions.
35 changes: 20 additions & 15 deletions src/components/fields/MultiSchemaField.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import * as types from "../../types";
import { guessType } from "../../utils";
import { getUiOptions, getWidget, guessType } from "../../utils";
import { isValid } from "../../validate";

class AnyOfField extends Component {
Expand Down Expand Up @@ -85,8 +85,8 @@ class AnyOfField extends Component {
return 0;
}

onOptionChange = event => {
const selectedOption = parseInt(event.target.value, 10);
onOptionChange = option => {
const selectedOption = parseInt(option, 10);
const { formData, onChange, options } = this.props;

const newOption = options[selectedOption];
Expand Down Expand Up @@ -119,7 +119,7 @@ class AnyOfField extends Component {
}

this.setState({
selectedOption: parseInt(event.target.value, 10),
selectedOption: parseInt(option, 10),
});
};

Expand All @@ -141,7 +141,10 @@ class AnyOfField extends Component {
} = this.props;

const _SchemaField = registry.fields.SchemaField;
const { widgets } = registry;
const { selectedOption } = this.state;
const { widget = "select", ...uiOptions } = getUiOptions(uiSchema);
const Widget = getWidget({ type: "number" }, widget, widgets);

const option = options[selectedOption] || null;
let optionSchema;
Expand All @@ -154,22 +157,24 @@ class AnyOfField extends Component {
: Object.assign({}, option, { type: baseType });
}

const enumOptions = options.map((option, index) => ({
label: option.title || `Option ${index + 1}`,
value: index,
}));

return (
<div className="panel panel-default panel-body">
<div className="form-group">
<select
className="form-control"
<Widget
id={`${idSchema.$id}_anyof_select`}
schema={{ type: "number", default: 0 }}
onChange={this.onOptionChange}
onBlur={onBlur}
onFocus={onFocus}
value={selectedOption}
id={`${idSchema.$id}_anyof_select`}>
{options.map((option, index) => {
return (
<option key={index} value={index}>
{option.title || `Option ${index + 1}`}
</option>
);
})}
</select>
options={{ enumOptions }}
{...uiOptions}
/>
</div>

{option !== null && (
Expand Down
30 changes: 30 additions & 0 deletions test/anyOf_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,36 @@ describe("anyOf", () => {
expect(node.querySelectorAll("select")).to.have.length.of(1);
});

it("should render a custom widget", () => {
const schema = {
type: "object",
anyOf: [
{
properties: {
foo: { type: "string" },
},
},
{
properties: {
bar: { type: "string" },
},
},
],
};
const widgets = {
SelectWidget: () => {
return <section id="CustomSelect">Custom Widget</section>;
},
};

const { node } = createFormComponent({
schema,
widgets,
});

expect(node.querySelector("#CustomSelect")).to.exist;
});

it("should change the rendered form when the select value is changed", () => {
const schema = {
type: "object",
Expand Down
30 changes: 30 additions & 0 deletions test/oneOf_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,36 @@ describe("oneOf", () => {
expect(node.querySelectorAll("select")).to.have.length.of(1);
});

it("should render a custom widget", () => {
const schema = {
type: "object",
oneOf: [
{
properties: {
foo: { type: "string" },
},
},
{
properties: {
bar: { type: "string" },
},
},
],
};
const widgets = {
SelectWidget: () => {
return <section id="CustomSelect">Custom Widget</section>;
},
};

const { node } = createFormComponent({
schema,
widgets,
});

expect(node.querySelector("#CustomSelect")).to.exist;
});

it("should change the rendered form when the select value is changed", () => {
const schema = {
type: "object",
Expand Down

0 comments on commit f8d0d45

Please # to comment.