Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 51 additions & 6 deletions docs/advanced-customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

_ | Custom Field | Custom Template | Custom Widget
--|---------- | ------------- | ----
What it does | Overrides all behaviour | Overrides just the layout | Overrides just the input box (not layout, labels, or help, or validation)
Usage | Global or per-field | Only global | Global or per-field
Global Example | `<Form fields={MyCustomFields} />` | `<Form ArrayFieldTemplate={ArrayFieldTemplate} />` | `<Form widgets={MyCustomWidgets} />`
Per-Field Example | `"ui:field": MyField` | N/A | `"ui:widget":MyWidget`
Documentation | [Field](#field-props) | [Field Template](#field-template) - [Array Template](#array-field-template) - [Object Template](#object-field-template) - [Error List Template](#error-list-template) | [Custom Widgets](#custom-widget-components)
**What it does** | Overrides all behaviour | Overrides just the layout (not behaviour) | Overrides just the input box (not layout, labels, or help, or validation)
**Usage** | Global or per-field | Global or per-field | Global or per-field
**Global Example** | `<Form fields={MyCustomField} />` | `<Form ArrayFieldTemplate={MyArrayTemplate} />` | `<Form widgets={MyCustomWidget} />`
**Per-Field Example** | `"ui:field": MyCustomField` | `"ui:ArrayFieldTemplate": MyArrayTemplate` | `"ui:widget":MyCustomWidget`
**Documentation** | [Field](#field-props) | [Field Template](#field-template) - [Array Template](#array-field-template) - [Object Template](#object-field-template) - [Error List Template](#error-list-template) | [Custom Widgets](#custom-widget-components)

### Field template

Expand Down Expand Up @@ -35,6 +35,19 @@ render((
), document.getElementById("app"));
```

You also can provide your own field template to a uiSchema by specifying a `ui:FieldTemplate` property.

```jsx
const uiSchema = {
"ui:FieldTemplate": CustomFieldTemplate
}

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

If you want to handle the rendering of each element yourself, you can use the props `rawHelp`, `rawDescription` and `rawErrors`.

The following props are passed to a custom field template component:
Expand All @@ -59,7 +72,7 @@ The following props are passed to a custom field template component:
- `uiSchema`: The uiSchema object for this field.
- `formContext`: The `formContext` object that you passed to Form.

> Note: you can only define a single field template for a form. If you need many, it's probably time to look at [custom fields](#custom-field-components) instead.
> Note: you can only define a single global field template for a form, but you can set individual field templates per property using `"ui:FieldTemplate"`.

### Array Field Template

Expand All @@ -82,8 +95,22 @@ render((
), document.getElementById("app"));
```

You also can provide your own field template to a uiSchema by specifying a `ui:ArrayFieldTemplate` property.

```jsx
const uiSchema = {
"ui:ArrayFieldTemplate": ArrayFieldTemplate
}

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

Please see [customArray.js](https://github.com/mozilla-services/react-jsonschema-form/blob/master/playground/samples/customArray.js) for a better example.


The following props are passed to each `ArrayFieldTemplate`:

- `DescriptionField`: The `DescriptionField` from the registry (in case you wanted to utilize it)
Expand Down Expand Up @@ -117,6 +144,8 @@ The following props are part of each element in `items`:
- `onReorderClick: (index, newIndex) => (event) => void`: Returns a function that swaps the items at `index` with `newIndex`.
- `readonly`: A boolean value stating if the array item is read-only.

> Note: Array and object field templates are always rendered inside of the FieldTemplate. To fully customize an array field template, you may need to specify both `ui:FieldTemplate` and `ui:ArrayFieldTemplate`.

### Object Field Template

Similarly to the `FieldTemplate` you can use an `ObjectFieldTemplate` to customize how your
Expand All @@ -139,6 +168,19 @@ render((
), document.getElementById("app"));
```

You also can provide your own field template to a uiSchema by specifying a `ui:ObjectFieldTemplate` property.

```jsx
const uiSchema = {
"ui:ObjectFieldTemplate": ObjectFieldTemplate
}

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

Please see [customObject.js](https://github.com/mozilla-services/react-jsonschema-form/blob/master/playground/samples/customObject.js) for a better example.

The following props are passed to each `ObjectFieldTemplate`:
Expand All @@ -164,6 +206,9 @@ The following props are part of each element in `properties`:
- `disabled`: A boolean value stating if the object property is disabled.
- `readonly`: A boolean value stating if the property is read-only.

> Note: Array and object field templates are always rendered inside of the FieldTemplate. To fully customize an object field template, you may need to specify both `ui:FieldTemplate` and `ui:ObjectFieldTemplate`.


### Error List template

To take control over how the form errors are displayed, you can define an *error list template* for your form. This list is the form global error list that appears at the top of your forms.
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"build:lib": "rimraf lib && cross-env NODE_ENV=production babel -d lib/ src/",
"build:dist": "rimraf dist && cross-env NODE_ENV=production webpack --config webpack.config.dist.js",
"build:playground": "rimraf build && cross-env NODE_ENV=production webpack --config webpack.config.prod.js && cp playground/index.prod.html build/index.html",
"cs-check": "prettier -l $npm_package_prettierOptions '{playground,src,test}/**/*.js'",
"cs-format": "prettier --jsx-bracket-same-line --trailing-comma es5 --use-tabs false --semi --tab-width 2 '{playground,src,test}/**/*.js' --write",
"cs-check": "prettier -l $npm_package_prettierOptions \"{playground,src,test}/**/*.js\"",
"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",
"prepare": "npm run dist",
Expand Down
10 changes: 8 additions & 2 deletions src/components/fields/ArrayField.js
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,10 @@ class ArrayField extends Component {
};

// Check if a custom render function was passed in
const Component = ArrayFieldTemplate || DefaultNormalArrayFieldTemplate;
const Component =
uiSchema["ui:ArrayFieldTemplate"] ||
ArrayFieldTemplate ||
DefaultNormalArrayFieldTemplate;
return <Component {...arrayProps} />;
}

Expand Down Expand Up @@ -670,7 +673,10 @@ class ArrayField extends Component {
};

// Check if a custom template template was passed in
const Template = ArrayFieldTemplate || DefaultFixedArrayFieldTemplate;
const Template =
uiSchema["ui:ArrayFieldTemplate"] ||
ArrayFieldTemplate ||
DefaultFixedArrayFieldTemplate;
return <Template {...arrayProps} />;
}

Expand Down
6 changes: 5 additions & 1 deletion src/components/fields/ObjectField.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,11 @@ class ObjectField extends Component {
);
}

const Template = registry.ObjectFieldTemplate || DefaultObjectFieldTemplate;
const Template =
uiSchema["ui:ObjectFieldTemplate"] ||
registry.ObjectFieldTemplate ||
DefaultObjectFieldTemplate;

const templateProps = {
title: uiSchema["ui:title"] || title,
description,
Expand Down
9 changes: 3 additions & 6 deletions src/components/fields/SchemaField.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,12 +236,9 @@ function SchemaFieldRender(props) {
required,
registry = getDefaultRegistry(),
} = props;
const {
definitions,
fields,
formContext,
FieldTemplate = DefaultTemplate,
} = registry;
const { definitions, fields, formContext } = registry;
const FieldTemplate =
uiSchema["ui:FieldTemplate"] || registry.FieldTemplate || DefaultTemplate;
let idSchema = props.idSchema;
const schema = retrieveSchema(props.schema, definitions, formData);
idSchema = mergeObjects(
Expand Down
Loading