Skip to content

Commit

Permalink
Add idPrefix option (Fix #796) (#806)
Browse files Browse the repository at this point in the history
  • Loading branch information
edi9999 authored Jan 13, 2018
1 parent 3e86b2a commit 51d403a
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 9 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -997,6 +997,19 @@ The following props are passed to `ErrorList`
- `uiSchema`: The uiSchema that was passed to `Form`.
- `formContext`: The `formContext` object that you passed to Form.

### Id prefix

To avoid collisions with existing ids in the DOM, it is possible to change the prefix used for ids (the default is `root`).

```jsx
render((
<Form schema={schema}
idPrefix={"rjsf_prefix"}/>,
), document.getElementById("app"));
```

This will render `<input id="rjsf_prefix_key">` instead of `<input id="root_key">`

### Custom widgets and fields

The API allows to specify your own custom *widget* and *field* components:
Expand Down
3 changes: 2 additions & 1 deletion src/components/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ export default class Form extends Component {
retrievedSchema,
uiSchema["ui:rootFieldId"],
definitions,
formData
formData,
props.idPrefix
);
return {
schema,
Expand Down
8 changes: 6 additions & 2 deletions src/components/fields/ArrayField.js
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ class ArrayField extends Component {
formContext,
onBlur,
onFocus,
idPrefix,
} = this.props;
const title = schema.title === undefined ? name : schema.title;
const { ArrayFieldTemplate, definitions, fields } = registry;
Expand All @@ -345,7 +346,8 @@ class ArrayField extends Component {
itemSchema,
itemIdPrefix,
definitions,
item
item,
idPrefix
);
return this.renderArrayFieldItem({
index,
Expand Down Expand Up @@ -464,6 +466,7 @@ class ArrayField extends Component {
uiSchema,
formData,
errorSchema,
idPrefix,
idSchema,
name,
required,
Expand Down Expand Up @@ -508,7 +511,8 @@ class ArrayField extends Component {
itemSchema,
itemIdPrefix,
definitions,
item
item,
idPrefix
);
const itemUiSchema = additional
? uiSchema.additionalItems || {}
Expand Down
1 change: 1 addition & 0 deletions src/components/widgets/TextWidget.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ function TextWidget(props) {
if (process.env.NODE_ENV !== "production") {
TextWidget.propTypes = {
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
id: PropTypes.string,
};
}

Expand Down
22 changes: 17 additions & 5 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -619,24 +619,36 @@ export function shouldRender(comp, nextProps, nextState) {
return !deepEquals(props, nextProps) || !deepEquals(state, nextState);
}

export function toIdSchema(schema, id, definitions, formData = {}) {
export function toIdSchema(
schema,
id,
definitions,
formData = {},
idPrefix = "root"
) {
const idSchema = {
$id: id || "root",
$id: id || idPrefix,
};
if ("$ref" in schema) {
const _schema = retrieveSchema(schema, definitions, formData);
return toIdSchema(_schema, id, definitions, formData);
return toIdSchema(_schema, id, definitions, formData, idPrefix);
}
if ("items" in schema && !schema.items.$ref) {
return toIdSchema(schema.items, id, definitions, formData);
return toIdSchema(schema.items, id, definitions, formData, idPrefix);
}
if (schema.type !== "object") {
return idSchema;
}
for (const name in schema.properties || {}) {
const field = schema.properties[name];
const fieldId = idSchema.$id + "_" + name;
idSchema[name] = toIdSchema(field, fieldId, definitions, formData[name]);
idSchema[name] = toIdSchema(
field,
fieldId,
definitions,
formData[name],
idPrefix
);
}
return idSchema;
}
Expand Down
24 changes: 24 additions & 0 deletions test/Form_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,30 @@ describe("Form", () => {
});
});

describe("Option idPrefix", function() {
it("should change the rendered ids", 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"]);
});
});

describe("Custom field template", () => {
const schema = {
type: "object",
Expand Down
1 change: 0 additions & 1 deletion test/StringField_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,6 @@ describe("StringField", () => {
},
});

console.log(node.querySelectorAll(".field option")[0].innerHTML);
expect(node.querySelectorAll(".field option")[0].textContent).eql("Test");
});

Expand Down
23 changes: 23 additions & 0 deletions test/utils_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,29 @@ describe("utils", () => {
bar: { $id: "root_bar" },
});
});

it("should handle idPrefix parameter", () => {
const schema = {
definitions: {
testdef: {
type: "object",
properties: {
foo: { type: "string" },
bar: { type: "string" },
},
},
},
$ref: "#/definitions/testdef",
};

expect(toIdSchema(schema, undefined, schema.definitions, {}, "rjsf")).eql(
{
$id: "rjsf",
foo: { $id: "rjsf_foo" },
bar: { $id: "rjsf_bar" },
}
);
});
});

describe("parseDateString()", () => {
Expand Down

1 comment on commit 51d403a

@jfroffice
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Please sign in to comment.