Skip to content

Commit

Permalink
Add idPrefix option (rjsf-team#883)
Browse files Browse the repository at this point in the history
  • Loading branch information
edi9999 authored Apr 10, 2018
1 parent 17ed8ff commit e4378c2
Show file tree
Hide file tree
Showing 14 changed files with 260 additions and 47 deletions.
20 changes: 13 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ A [live playground](https://mozilla-services.github.io/react-jsonschema-form/) i
- [Form error event handler](#form-error-event-handler)
- [Form data changes](#form-data-changes)
- [Form field blur events](#form-field-blur-events)
- [Form field focus events](#form-field-focus-events)
- [Form customization](#form-customization)
- [The uiSchema object](#the-uischema-object)
- [Alternative widgets](#alternative-widgets)
Expand All @@ -42,7 +43,8 @@ A [live playground](https://mozilla-services.github.io/react-jsonschema-form/) i
- [removable option](#removable-option)
- [Custom CSS class names](#custom-css-class-names)
- [Custom labels for enum fields](#custom-labels-for-enum-fields)
- [Disabled enum fields](#disabled-attribute-for-enum-fields)
- [Alternative JSON-Schema compliant approach](#alternative-json-schema-compliant-approach)
- [Disabled attribute for enum fields](#disabled-attribute-for-enum-fields)
- [Multiple choices list](#multiple-choices-list)
- [Autogenerated widget ids](#autogenerated-widget-ids)
- [Form action buttons](#form-action-buttons)
Expand All @@ -60,11 +62,12 @@ A [live playground](https://mozilla-services.github.io/react-jsonschema-form/) i
- [Array Field Template](#array-field-template)
- [Object Field Template](#object-field-template)
- [Error List template](#error-list-template)
- [Id prefix](#id-prefix)
- [Custom widgets and fields](#custom-widgets-and-fields)
- [Custom widget components](#custom-widget-components)
- [Custom component registration](#custom-component-registration)
- [Custom widget options](#custom-widget-options)
- [Customizing widgets' text input](#customizing-widgets-text-input)
- [Customizing widgets text input](#customizing-widgets-text-input)
- [Custom field components](#custom-field-components)
- [Field props](#field-props)
- [The registry object](#the-registry-object)
Expand All @@ -84,19 +87,22 @@ A [live playground](https://mozilla-services.github.io/react-jsonschema-form/) i
- [Styling your forms](#styling-your-forms)
- [Schema definitions and references](#schema-definitions-and-references)
- [Property dependencies](#property-dependencies)
- [Unidirectional](#unidirectional)
- [Bidirectional](#bidirectional)
- [Unidirectional](#unidirectional)
- [Bidirectional](#bidirectional)
- [Schema dependencies](#schema-dependencies)
- [Conditional](#conditional)
- [Dynamic](#dynamic)
- [Conditional](#conditional)
- [Dynamic](#dynamic)
- [JSON Schema supporting status](#json-schema-supporting-status)
- [Tips and tricks](#tips-and-tricks)
- [Contributing](#contributing)
- [Coding style](#coding-style)
- [Development server](#development-server)
- [Tests](#tests)
- [TDD](#tdd)
- [Releasing](#releasing)
- [FAQ](#faq)
- [Q: Does rjsf support oneOf, anyOf, multiple types in an array, etc.?](#q-does-rjsf-support-oneof-anyof-multiple-types-in-an-array-etc)
- [Q: Will react-jsonschema-form support Material, Ant-Design, Foundation, or [some other specific widget library or frontend style]?](#q-will-react-jsonschema-form-support-material-ant-design-foundation-or-some-other-specific-widget-library-or-frontend-style)
- [License](#license)

---
Expand Down Expand Up @@ -1184,7 +1190,7 @@ render((
> Note: Since v0.41.0, the `ui:widget` object API, where a widget and options were specified with `"ui:widget": {component, options}` shape, is deprecated. It will be removed in a future release.
#### Customizing widgets' text input
#### Customizing widgets text input

All the widgets that render a text input use the `BaseInput` component internally. If you need to customize all text inputs without customizing all widgets individially, you can provide a `BaseInput` component in the `widgets` property of `Form` (see [Custom component registration](#custom-component-registration).

Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,18 @@
"build:dist": "rimraf dist && cross-env NODE_ENV=production webpack --config webpack.config.dist.js --optimize-minimize",
"build:playground": "rimraf build && cross-env NODE_ENV=production webpack --config webpack.config.prod.js --optimize-minimize && cp playground/index.prod.html build/index.html",
"cs-check": "prettier -l $npm_package_prettierOptions '{playground,src,test}/**/*.js'",
"cs-format": "prettier $npm_package_prettierOptions '{playground,src,test}/**/*.js' --write",
"cs-format": "prettier --jsx-bracket-same-line --trailing-comma es5 --use-tabs false --semi --tab-width 2 '{playground,src,test}/**/*.js' --write",
"dist": "npm run build:lib && npm run build:dist",
"lint": "eslint src test playground",
"precommit": "lint-staged",
"publish-to-gh-pages": "npm run build:playground && gh-pages --dist build/",
"publish-to-npm": "npm run build:readme && npm run dist && npm publish",
"preversion": "npm run build:playground && npm run dist && npm run build:readme && npm run cs-check && npm run lint",
"start": "node devServer.js",
"tdd": "cross-env NODE_ENV=test mocha --compilers js:babel-register --watch --require ./test/setup-jsdom.js test/**/*_test.js",
"test": "cross-env NODE_ENV=test mocha --compilers js:babel-register --require ./test/setup-jsdom.js test/**/*_test.js"
},
"prettierOptions": "--jsx-bracket-same-line --trailing-comma es5 --semi",
"prettierOptions": "--jsx-bracket-same-line --trailing-comma es5 --semi --tab-width 2",
"lint-staged": {
"{playground,src,test}/**/*.js": [
"npm run lint",
Expand Down
2 changes: 2 additions & 0 deletions src/components/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ export default class Form extends Component {
children,
safeRenderCompletion,
id,
idPrefix,
className,
name,
method,
Expand Down Expand Up @@ -209,6 +210,7 @@ export default class Form extends Component {
uiSchema={uiSchema}
errorSchema={errorSchema}
idSchema={idSchema}
idPrefix={idPrefix}
formData={formData}
onChange={this.onChange}
onBlur={this.onBlur}
Expand Down
5 changes: 4 additions & 1 deletion src/components/fields/ArrayField.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@ function DefaultArrayItem(props) {
<div className="col-xs-3 array-item-toolbox">
<div
className="btn-group"
style={{ display: "flex", justifyContent: "space-around" }}>
style={{
display: "flex",
justifyContent: "space-around",
}}>
{(props.hasMoveUp || props.hasMoveDown) && (
<IconBtn
icon="arrow-up"
Expand Down
2 changes: 2 additions & 0 deletions src/components/fields/ObjectField.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class ObjectField extends Component {
required,
disabled,
readonly,
idPrefix,
onBlur,
onFocus,
registry = getDefaultRegistry(),
Expand Down Expand Up @@ -117,6 +118,7 @@ class ObjectField extends Component {
uiSchema={uiSchema[name]}
errorSchema={errorSchema[name]}
idSchema={idSchema[name]}
idPrefix={idPrefix}
formData={formData[name]}
onChange={this.onPropertyChange(name)}
onBlur={onBlur}
Expand Down
10 changes: 9 additions & 1 deletion src/components/fields/SchemaField.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import PropTypes from "prop-types";
import {
isMultiSelect,
retrieveSchema,
toIdSchema,
getDefaultRegistry,
mergeObjects,
getUiOptions,
isFilesArray,
deepEquals,
Expand Down Expand Up @@ -153,7 +155,7 @@ function SchemaFieldRender(props) {
uiSchema,
formData,
errorSchema,
idSchema,
idPrefix,
name,
required,
registry = getDefaultRegistry(),
Expand All @@ -164,7 +166,12 @@ function SchemaFieldRender(props) {
formContext,
FieldTemplate = DefaultTemplate,
} = registry;
let idSchema = props.idSchema;
const schema = retrieveSchema(props.schema, definitions, formData);
idSchema = mergeObjects(
toIdSchema(schema, null, definitions, formData, idPrefix),
idSchema
);
const FieldComponent = getFieldComponent(schema, uiSchema, idSchema, fields);
const { DescriptionField } = fields;
const disabled = Boolean(props.disabled || uiSchema["ui:disabled"]);
Expand Down Expand Up @@ -199,6 +206,7 @@ function SchemaFieldRender(props) {
const field = (
<FieldComponent
{...props}
idSchema={idSchema}
schema={schema}
uiSchema={{ ...uiSchema, classNames: undefined }}
disabled={disabled}
Expand Down
4 changes: 4 additions & 0 deletions src/components/widgets/BaseInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import PropTypes from "prop-types";
function BaseInput(props) {
// Note: since React 15.2.0 we can't forward unknown element attributes, so we
// exclude the "options" and "schema" ones here.
if (!props.id) {
console.log("No id for", props);
throw new Error(`no id for props ${JSON.stringify(props)}`);
}
const {
value,
readonly,
Expand Down
15 changes: 12 additions & 3 deletions test/ArrayField_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,10 @@ describe("ArrayField", () => {
},
},
};
let form = createFormComponent({ schema: complexSchema, formData: {} });
let form = createFormComponent({
schema: complexSchema,
formData: {},
});
let inputs = form.node.querySelectorAll("input[type=text]");
expect(inputs[0].value).eql("Default name");
expect(inputs[1].value).eql("Default name");
Expand Down Expand Up @@ -726,7 +729,10 @@ describe("ArrayField", () => {
});

it("should handle a change event", () => {
const { comp, node } = createFormComponent({ schema, uiSchema });
const { comp, node } = createFormComponent({
schema,
uiSchema,
});

Simulate.change(node.querySelectorAll("[type=checkbox]")[0], {
target: { checked: true },
Expand Down Expand Up @@ -1058,7 +1064,10 @@ describe("ArrayField", () => {
});

it("should fill fields with data", () => {
const { node } = createFormComponent({ schema, formData: ["foo", 42] });
const { node } = createFormComponent({
schema,
formData: ["foo", 42],
});
const strInput = node.querySelector(
"fieldset .field-string input[type=text]"
);
Expand Down
110 changes: 103 additions & 7 deletions test/Form_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,85 @@ describe("Form", () => {
});
});

describe("Changing idPrefix", function() {
it("should work with simple example", function() {
const schema = {
type: "object",
title: "root object",
required: ["foo"],
properties: {
count: {
type: "number",
},
},
};
const comp = renderIntoDocument(<Form schema={schema} idPrefix="rjsf" />);
const node = findDOMNode(comp);
const inputs = node.querySelectorAll("input");
const ids = [];
for (var i = 0, len = inputs.length; i < len; i++) {
const input = inputs[i];
ids.push(input.getAttribute("id"));
}
expect(ids).to.eql(["rjsf_count"]);
});

it("should work with oneOf", function() {
const schema = {
$schema: "http://json-schema.org/draft-06/schema#",
type: "object",
properties: {
connector: {
type: "string",
enum: ["aws", "gcp"],
title: "Provider",
default: "aws",
},
},
dependencies: {
connector: {
oneOf: [
{
type: "object",
properties: {
connector: {
type: "string",
enum: ["aws"],
},
key_aws: {
type: "string",
},
},
},
{
type: "object",
properties: {
connector: {
type: "string",
enum: ["gcp"],
},
key_gcp: {
type: "string",
},
},
},
],
},
},
};

const comp = renderIntoDocument(<Form schema={schema} idPrefix="rjsf" />);
const node = findDOMNode(comp);
const inputs = node.querySelectorAll("input");
const ids = [];
for (var i = 0, len = inputs.length; i < len; i++) {
const input = inputs[i];
ids.push(input.getAttribute("id"));
}
expect(ids).to.eql(["rjsf_key_aws"]);
});
});

describe("Custom field template", () => {
const schema = {
type: "object",
Expand Down Expand Up @@ -592,7 +671,11 @@ describe("Form", () => {
foo: "",
};
const onChange = sandbox.spy();
const { node } = createFormComponent({ schema, formData, onChange });
const { node } = createFormComponent({
schema,
formData,
onChange,
});

Simulate.change(node.querySelector("[type=text]"), {
target: { value: "new" },
Expand Down Expand Up @@ -835,7 +918,10 @@ describe("Form", () => {
});

it("should denote the new error in the field", () => {
const { node } = createFormComponent({ schema, liveValidate: true });
const { node } = createFormComponent({
schema,
liveValidate: true,
});

Simulate.change(node.querySelector("input[type=text]"), {
target: { value: "short" },
Expand Down Expand Up @@ -1056,7 +1142,9 @@ describe("Form", () => {
const { comp } = createFormComponent(formProps);

expect(comp.state.errorSchema).eql({
1: { __errors: ["should NOT be shorter than 4 characters"] },
1: {
__errors: ["should NOT be shorter than 4 characters"],
},
});
});

Expand Down Expand Up @@ -1108,8 +1196,12 @@ describe("Form", () => {

expect(comp.state.errorSchema).eql({
level1: {
1: { __errors: ["should NOT be shorter than 4 characters"] },
3: { __errors: ["should NOT be shorter than 4 characters"] },
1: {
__errors: ["should NOT be shorter than 4 characters"],
},
3: {
__errors: ["should NOT be shorter than 4 characters"],
},
},
});
});
Expand Down Expand Up @@ -1158,10 +1250,14 @@ describe("Form", () => {
expect(comp.state.errorSchema).eql({
outer: {
0: {
1: { __errors: ["should NOT be shorter than 4 characters"] },
1: {
__errors: ["should NOT be shorter than 4 characters"],
},
},
1: {
0: { __errors: ["should NOT be shorter than 4 characters"] },
0: {
__errors: ["should NOT be shorter than 4 characters"],
},
},
},
});
Expand Down
4 changes: 3 additions & 1 deletion test/NumberField_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ describe("NumberField", () => {
});

it("should default state value to undefined", () => {
const { comp } = createFormComponent({ schema: { type: "number" } });
const { comp } = createFormComponent({
schema: { type: "number" },
});

expect(comp.state.formData).eql(undefined);
});
Expand Down
Loading

0 comments on commit e4378c2

Please sign in to comment.