Skip to content

Commit 3f36b18

Browse files
olzraitin1k0
authored andcommitted
Add support for form context (rjsf-team#285)
1 parent 1722ab2 commit 3f36b18

File tree

12 files changed

+137
-13
lines changed

12 files changed

+137
-13
lines changed

README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ A [live playground](https://mozilla-services.github.io/react-jsonschema-form/) i
5050
- [Custom field components](#custom-field-components)
5151
- [Field props](#field-props)
5252
- [The registry object](#the-registry-object)
53+
- [The formContext object](#the-formcontext-object)
5354
- [Custom SchemaField](#custom-schemafield)
5455
- [Custom titles](#custom-titles)
5556
- [Custom descriptions](#custom-descriptions)
@@ -592,6 +593,7 @@ The following props are passed to a custom field template component:
592593
- `required`: A boolean value stating if the field is required;
593594
- `readonly`: A boolean value stating if the field is read-only;
594595
- `displayLabel`: A boolean value stating if the label should be rendered or not. This is useful for nested fields in arrays where you don't want to clutter the UI.
596+
- `formContext`: The `formContext` object that you passed to Form.
595597

596598
> Note: you can only define a single field template for a form. If you need many, it's probably time to look for [custom fields](#custom-field-components) instead.
597599
@@ -643,6 +645,7 @@ The following props are passed to custom widget components:
643645
- `readonly`: `true` if the widget is read-only;
644646
- `onChange`: The value change event handler; call it with the new value everytime it changes;
645647
- `options`: A map of options passed as a prop to the component (see [Custom widget options](#custom-widget-options)).
648+
- `formContext`: The `formContext` object that you passed to Form.
646649

647650
> Note: Prior to v0.35.0, the `options` prop contained the list of options (`label` and `value`) for `enum` fields. Since v0.35.0, it now exposes this list as the `enumOptions` property within the `options` object.
648651
@@ -769,7 +772,7 @@ render((
769772
), document.getElementById("app"));
770773
```
771774

772-
> Note: Registered fields can be reused accross the entire schema.
775+
> Note: Registered fields can be reused across the entire schema.
773776
774777
#### Field props
775778

@@ -781,6 +784,7 @@ A field component will always be passed the following props:
781784
- `formData`: The data for this field;
782785
- `errorSchema`: The tree of errors for this field and its children;
783786
- `registry`: A [registry](#the-registry-object) object (read next).
787+
- `formContext`: A [formContext](#the-formcontext-object) object (read next next).
784788

785789
#### The `registry` object
786790

@@ -789,9 +793,14 @@ The `registry` is an object containing the registered custom fields and widgets
789793
- `fields`: The [custom registered fields](#custom-field-components). By default this object contains the standard `SchemaField`, `TitleField` and `DescriptionField` components;
790794
- `widgets`: The [custom registered widgets](#custom-widget-components), if any;
791795
- `definitions`: The root schema [definitions](#schema-definitions-and-references), if any.
796+
- `formContext`: The [formContext](#the-formcontext-object) object.
792797

793798
The registry is passed down the component tree, so you can access it from your custom field and `SchemaField` components.
794799

800+
#### The `formContext` object
801+
802+
You can provide a `formContext` object to the Form, which is passed down to all fields and widgets (including [TitleField](#custom-titles) and [DescriptionField](#custom-descriptions)). Useful for implementing context aware fields and widgets.
803+
795804
### Custom SchemaField
796805

797806
**Warning:** This is a powerful feature as you can override the whole form behavior and easily mess it up. Handle with care.

src/components/Form.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ export default class Form extends Component {
132132
FieldTemplate: this.props.FieldTemplate,
133133
widgets: this.props.widgets || {},
134134
definitions: this.props.schema.definitions || {},
135+
formContext: this.props.formContext || {},
135136
};
136137
}
137138

@@ -211,7 +212,6 @@ if (process.env.NODE_ENV !== "production") {
211212
noValidate: PropTypes.bool,
212213
liveValidate: PropTypes.bool,
213214
safeRenderCompletion: PropTypes.bool,
215+
formContext: PropTypes.object,
214216
};
215217
}
216-
217-
export default Form;

src/components/fields/ArrayField.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,8 @@ if (process.env.NODE_ENV !== "production") {
410410
])).isRequired,
411411
fields: PropTypes.objectOf(PropTypes.func).isRequired,
412412
definitions: PropTypes.object.isRequired,
413-
})
413+
formContext: PropTypes.object.isRequired
414+
}),
414415
};
415416
}
416417

src/components/fields/BooleanField.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ function BooleanField(props) {
3232
onChange
3333
} = props;
3434
const {title} = schema;
35-
const {widgets} = registry;
35+
const {widgets, formContext} = registry;
3636
const widget = uiSchema["ui:widget"];
3737
const commonProps = {
3838
schema,
@@ -43,6 +43,8 @@ function BooleanField(props) {
4343
required,
4444
disabled,
4545
readonly,
46+
registry,
47+
formContext,
4648
};
4749
if (widget) {
4850
const Widget = getAlternativeWidget(schema, widget, widgets);
@@ -68,6 +70,7 @@ if (process.env.NODE_ENV !== "production") {
6870
])).isRequired,
6971
fields: PropTypes.objectOf(PropTypes.func).isRequired,
7072
definitions: PropTypes.object.isRequired,
73+
formContext: PropTypes.object.isRequired,
7174
})
7275
};
7376
}

src/components/fields/DescriptionField.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ if (process.env.NODE_ENV !== "production") {
1818
description: PropTypes.oneOfType([
1919
PropTypes.string,
2020
PropTypes.element,
21-
]),
21+
])
2222
};
2323
}
2424

src/components/fields/NumberField.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ if (process.env.NODE_ENV !== "production") {
1818
onChange: PropTypes.func.isRequired,
1919
formData: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
2020
required: PropTypes.bool,
21+
formContext: PropTypes.object.isRequired,
2122
};
2223
}
2324

src/components/fields/ObjectField.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class ObjectField extends Component {
9393
disabled,
9494
readonly
9595
} = this.props;
96-
const {definitions, fields} = this.props.registry;
96+
const {definitions, fields, formContext} = this.props.registry;
9797
const {SchemaField, TitleField, DescriptionField} = fields;
9898
const schema = retrieveSchema(this.props.schema, definitions);
9999
const title = schema.title || name;
@@ -117,12 +117,13 @@ class ObjectField extends Component {
117117
{title ? <TitleField
118118
id={`${idSchema.$id}__title`}
119119
title={title}
120-
required={required} /> : null}
120+
required={required}
121+
formContext={formContext}/> : null}
121122
{schema.description ?
122123
<DescriptionField
123124
id={`${idSchema.$id}__description`}
124125
description={schema.description}
125-
/> : null}
126+
formContext={formContext} /> : null}
126127
{
127128
orderedProperties.map((name, index) => {
128129
return (
@@ -163,6 +164,7 @@ if (process.env.NODE_ENV !== "production") {
163164
])).isRequired,
164165
fields: PropTypes.objectOf(PropTypes.func).isRequired,
165166
definitions: PropTypes.object.isRequired,
167+
formContext: PropTypes.object.isRequired,
166168
})
167169
};
168170
}

src/components/fields/SchemaField.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ if (process.env.NODE_ENV !== "production") {
115115
required: PropTypes.bool,
116116
readonly: PropTypes.bool,
117117
displayLabel: PropTypes.bool,
118+
formContext: PropTypes.object,
118119
};
119120
}
120121

@@ -127,7 +128,7 @@ DefaultTemplate.defaultProps = {
127128

128129
function SchemaField(props) {
129130
const {uiSchema, errorSchema, idSchema, name, required, registry} = props;
130-
const {definitions, fields, FieldTemplate = DefaultTemplate} = registry;
131+
const {definitions, fields, formContext, FieldTemplate = DefaultTemplate} = registry;
131132
const schema = retrieveSchema(props.schema, definitions);
132133
const FieldComponent = getFieldComponent(schema, uiSchema, fields);
133134
const {DescriptionField} = fields;
@@ -156,7 +157,8 @@ function SchemaField(props) {
156157
<FieldComponent {...props}
157158
schema={schema}
158159
disabled={disabled}
159-
readonly={readonly} />
160+
readonly={readonly}
161+
formContext={formContext} />
160162
);
161163

162164
const {type} = schema;
@@ -175,7 +177,9 @@ function SchemaField(props) {
175177
].join(" ").trim();
176178

177179
const fieldProps = {
178-
description: <DescriptionField id={id + "__description"} description={description} />,
180+
description: <DescriptionField id={id + "__description"}
181+
description={description}
182+
formContext={formContext} />,
179183
help: <Help help={help} />,
180184
errors: <ErrorList errors={errors} />,
181185
id,
@@ -185,6 +189,7 @@ function SchemaField(props) {
185189
readonly,
186190
displayLabel,
187191
classNames,
192+
formContext,
188193
};
189194

190195
return <FieldTemplate {...fieldProps}>{field}</FieldTemplate>;
@@ -214,6 +219,7 @@ if (process.env.NODE_ENV !== "production") {
214219
fields: PropTypes.objectOf(PropTypes.func).isRequired,
215220
definitions: PropTypes.object.isRequired,
216221
FieldTemplate: PropTypes.func,
222+
formContext: PropTypes.object.isRequired,
217223
})
218224
};
219225
}

src/components/fields/StringField.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ function StringField(props) {
2424
onChange
2525
} = props;
2626
const {title} = schema;
27-
const {widgets} = registry;
27+
const {widgets, formContext} = registry;
2828
const widget = uiSchema["ui:widget"] || schema.format;
2929
const placeholder = uiSchema["ui:placeholder"] || "";
3030
const commonProps = {
@@ -36,6 +36,7 @@ function StringField(props) {
3636
required,
3737
disabled,
3838
readonly,
39+
formContext,
3940
};
4041
if (Array.isArray(schema.enum)) {
4142
const enumOptions = optionsList(schema);
@@ -69,7 +70,9 @@ if (process.env.NODE_ENV !== "production") {
6970
])).isRequired,
7071
fields: PropTypes.objectOf(PropTypes.func).isRequired,
7172
definitions: PropTypes.object.isRequired,
73+
formContext: PropTypes.object.isRequired,
7274
}),
75+
formContext: PropTypes.object.isRequired,
7376
required: PropTypes.bool,
7477
disabled: PropTypes.bool,
7578
readonly: PropTypes.bool,

src/components/widgets/BaseInput.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ function BaseInput(props) {
1010
onChange,
1111
options, // eslint-disable-line
1212
schema, // eslint-disable-line
13+
formContext, // eslint-disable-line
1314
...inputProps
1415
} = props;
1516
return (

0 commit comments

Comments
 (0)