diff --git a/README.md b/README.md
index 3bd743b3ef..996e967c1d 100644
--- a/README.md
+++ b/README.md
@@ -42,6 +42,8 @@ A [live playground](https://mozilla-services.github.io/react-jsonschema-form/) i
- [Placeholders](#placeholders)
- [Form attributes](#form-attributes)
- [Advanced customization](#advanced-customization)
+ - [Field template](#field-template)
+ - [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)
@@ -551,7 +553,51 @@ Form component supports the following html attributes:
## Advanced customization
-The API allows to specify your own custom *widgets* and *fields* components:
+### Field template
+
+To take control over the inner organization of each field (each form row), you can define a *field template* for your form.
+
+A field template is basically a React stateless component being passed field-related props so you can structure your form row as you like:
+
+```jsx
+function CustomFieldTemplate(props) {
+ const {id, classNames, label, help, required, description, errors, children} = props;
+ return (
+
+ );
+}
+
+render((
+ ,
+), document.getElementById("app"));
+```
+
+The following props are passed to a custom field template component:
+
+- `id`: The id of the field in the hierarchy. You can use it to render a label targetting the wrapped widget;
+- `classNames`: A string containing the base bootstrap CSS classes merged with any [custom ones](#custom-css-class-names) defined in your uiSchema;
+- `label`: The computed label for this field, as a string;
+- `description`: A component instance rendering the field description, if any defined (this will use any [custom `DescriptionField`](#custom-descriptions) defined);
+- `children`: The field or widget component instance for this field row;
+- `errors`: A component instance listing any encountered errors for this field;
+- `help`: A component instance rendering any `ui:help` uiSchema directive defined;
+- `hidden`: A boolean value stating if the field should be hidden;
+- `required`: A boolean value stating if the field is required;
+- `readonly`: A boolean value stating if the field is read-only;
+- `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.
+
+> 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.
+
+### Custom widgets and fields
+
+The API allows to specify your own custom *widget* and *field* components:
- A *widget* represents a HTML tag for the user to enter data, eg. `input`, `select`, etc.
- A *field* usually wraps one or more widgets and most often handles internal field state; think of a field as a form row, including the labels.
diff --git a/playground/samples/date.js b/playground/samples/date.js
index 7517699b08..cb5b25ecc1 100644
--- a/playground/samples/date.js
+++ b/playground/samples/date.js
@@ -20,7 +20,7 @@ module.exports = {
},
alternative: {
title: "Alternative",
- description: "These work on every platform.",
+ description: "These work on most platforms.",
type: "object",
properties: {
"alt-datetime": {
diff --git a/src/components/Form.js b/src/components/Form.js
index 9cd54957b0..0f33e8e2e0 100644
--- a/src/components/Form.js
+++ b/src/components/Form.js
@@ -125,10 +125,11 @@ export default class Form extends Component {
const fields = Object.assign({
SchemaField: _SchemaField,
TitleField: _TitleField,
- DescriptionField: _DescriptionField
+ DescriptionField: _DescriptionField,
}, this.props.fields);
return {
fields,
+ FieldTemplate: this.props.FieldTemplate,
widgets: this.props.widgets || {},
definitions: this.props.schema.definitions || {},
};
@@ -193,6 +194,7 @@ if (process.env.NODE_ENV !== "production") {
PropTypes.object,
])),
fields: PropTypes.objectOf(PropTypes.func),
+ FieldTemplate: PropTypes.func,
onChange: PropTypes.func,
onError: PropTypes.func,
showErrorList: PropTypes.bool,
diff --git a/src/components/fields/DescriptionField.js b/src/components/fields/DescriptionField.js
index 0082475caf..4d63845f1d 100644
--- a/src/components/fields/DescriptionField.js
+++ b/src/components/fields/DescriptionField.js
@@ -2,6 +2,9 @@ import React, {PropTypes} from "react";
function DescriptionField(props) {
const {id, description} = props;
+ if (!description) {
+ return null;
+ }
if (typeof description === "string") {
return