diff --git a/src/components/Form.js b/src/components/Form.js
index 98fed2f7ee..fd15052332 100644
--- a/src/components/Form.js
+++ b/src/components/Form.js
@@ -79,11 +79,12 @@ export default class Form extends Component {
return {
SchemaField: this.props.SchemaField || SchemaField,
TitleField: this.props.TitleField || TitleField,
+ widgets: this.props.widgets || {},
};
}
render() {
- const {children, schema, uiSchema} = this.props;
+ const {children, schema, uiSchema, widgets} = this.props;
const {formData} = this.state;
const registry = this.getRegistry();
const _SchemaField = registry.SchemaField;
@@ -94,6 +95,7 @@ export default class Form extends Component {
schema={schema}
uiSchema={uiSchema}
formData={formData}
+ widgets={widgets}
onChange={this.onChange.bind(this)}
registry={registry}/>
{ children ? children :
}
@@ -107,6 +109,7 @@ if (process.env.NODE_ENV !== "production") {
schema: PropTypes.object.isRequired,
uiSchema: PropTypes.object,
formData: PropTypes.any,
+ widgets: PropTypes.object,
onChange: PropTypes.func,
onError: PropTypes.func,
onSubmit: PropTypes.func,
diff --git a/src/components/fields/ArrayField.js b/src/components/fields/ArrayField.js
index 837aeea7a1..b231c7e2eb 100644
--- a/src/components/fields/ArrayField.js
+++ b/src/components/fields/ArrayField.js
@@ -69,7 +69,7 @@ class ArrayField extends Component {
const {schema, uiSchema, name} = this.props;
const title = schema.title || name;
const {items} = this.state;
- const SchemaField = this.props.registry.SchemaField;
+ const {SchemaField} = this.props.registry;
if (isMultiSelect(schema)) {
return (
;
}
return ;
diff --git a/src/components/fields/ObjectField.js b/src/components/fields/ObjectField.js
index 7b12f047d5..4bcc77512c 100644
--- a/src/components/fields/ObjectField.js
+++ b/src/components/fields/ObjectField.js
@@ -67,7 +67,7 @@ class ObjectField extends Component {
formData={this.state[name]}
onChange={this.onChange.bind(this, name)}
registry={this.props.registry} />
- );
+ );
})
}
);
diff --git a/src/components/fields/SchemaField.js b/src/components/fields/SchemaField.js
index ffa3f2399a..491accf131 100644
--- a/src/components/fields/SchemaField.js
+++ b/src/components/fields/SchemaField.js
@@ -98,6 +98,7 @@ if (process.env.NODE_ENV !== "production") {
SchemaField.propTypes = {
schema: PropTypes.object.isRequired,
uiSchema: PropTypes.object,
+ registry: PropTypes.object,
};
}
diff --git a/src/components/fields/StringField.js b/src/components/fields/StringField.js
index d496a34a93..833dce108d 100644
--- a/src/components/fields/StringField.js
+++ b/src/components/fields/StringField.js
@@ -5,7 +5,8 @@ import TextWidget from "./../widgets/TextWidget";
import SelectWidget from "./../widgets/SelectWidget";
-function StringField({schema, name, uiSchema, formData, required, onChange}) {
+function StringField(props) {
+ const {schema, widgets, name, uiSchema, formData, required, onChange} = props;
const {title, description} = schema;
const widget = uiSchema["ui:widget"];
const commonProps = {
@@ -19,13 +20,13 @@ function StringField({schema, name, uiSchema, formData, required, onChange}) {
};
if (Array.isArray(schema.enum)) {
if (widget) {
- const Widget = getAlternativeWidget(schema.type, widget);
+ const Widget = getAlternativeWidget(schema.type, widget, widgets);
return ;
}
return ;
}
if (widget) {
- const Widget = getAlternativeWidget(schema.type, widget);
+ const Widget = getAlternativeWidget(schema.type, widget, widgets);
return ;
}
return ;
diff --git a/src/utils.js b/src/utils.js
index 6ad084ce30..6513f22d38 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -43,13 +43,16 @@ export function defaultFieldValue(formData, schema) {
return formData === null ? defaultTypeValue(schema.type) : formData;
}
-export function getAlternativeWidget(type, widget) {
+export function getAlternativeWidget(type, widget, registeredWidgets={}) {
if (typeof widget === "function") {
return widget;
}
if (typeof widget !== "string") {
throw new Error(`Unsupported widget definition: ${typeof widget}`);
}
+ if (widget in registeredWidgets) {
+ return registeredWidgets[widget];
+ }
if (!altWidgetMap.hasOwnProperty(type)) {
throw new Error(`No alternative widget for type ${type}`);
}
diff --git a/test/index_test.js b/test/index_test.js
index fd31aae7ab..0a49186981 100644
--- a/test/index_test.js
+++ b/test/index_test.js
@@ -91,6 +91,26 @@ describe("Form", () => {
});
});
+ describe("Custom widgets", () => {
+ it("should support custom StringField widgets", () => {
+ const schema = {type: "string"};
+ const uiSchema = {"ui:widget": "foo"};
+ const foo = () => yo
;
+ const {node} = createComponent({schema, uiSchema, widgets: {foo}});
+
+ expect(node.querySelector("#custom").textContent).eql("yo");
+ });
+
+ it("should support custom BooleanField widgets", () => {
+ const schema = {type: "boolean"};
+ const uiSchema = {"ui:widget": "foo"};
+ const foo = () => yo
;
+ const {node} = createComponent({schema, uiSchema, widgets: {foo}});
+
+ expect(node.querySelector("#custom").textContent).eql("yo");
+ });
+ });
+
describe("Object fields ordering", () => {
const schema = {
type: "object",