react-jsonschema-form
Advanced tools
Comparing version 0.16.2 to 0.17.0
@@ -144,4 +144,5 @@ "use strict"; | ||
var _props$registry = this.props.registry; | ||
var SchemaField = _props$registry.SchemaField; | ||
var fields = _props$registry.fields; | ||
var definitions = _props$registry.definitions; | ||
var SchemaField = fields.SchemaField; | ||
@@ -232,4 +233,4 @@ var itemsSchema = (0, _utils.retrieveSchema)(schema.items, definitions); | ||
registry: _react.PropTypes.shape({ | ||
SchemaField: _react.PropTypes.func.isRequired, | ||
TitleField: _react.PropTypes.func.isRequired | ||
widgets: _react.PropTypes.objectOf(_react.PropTypes.func).isRequired, | ||
fields: _react.PropTypes.objectOf(_react.PropTypes.func).isRequired | ||
}) | ||
@@ -236,0 +237,0 @@ }; |
@@ -99,5 +99,6 @@ "use strict"; | ||
var _props$registry = this.props.registry; | ||
var SchemaField = _props$registry.SchemaField; | ||
var TitleField = _props$registry.TitleField; | ||
var definitions = _props$registry.definitions; | ||
var fields = _props$registry.fields; | ||
var SchemaField = fields.SchemaField; | ||
var TitleField = fields.TitleField; | ||
@@ -168,4 +169,4 @@ var schema = (0, _utils.retrieveSchema)(this.props.schema, definitions); | ||
registry: _react.PropTypes.shape({ | ||
SchemaField: _react.PropTypes.func.isRequired, | ||
TitleField: _react.PropTypes.func.isRequired | ||
widgets: _react.PropTypes.objectOf(_react.PropTypes.func).isRequired, | ||
fields: _react.PropTypes.objectOf(_react.PropTypes.func).isRequired | ||
}) | ||
@@ -172,0 +173,0 @@ }; |
@@ -50,2 +50,13 @@ "use strict"; | ||
function getFieldComponent(schema, uiSchema, fields) { | ||
var field = uiSchema["ui:field"]; | ||
if (typeof field === "function") { | ||
return field; | ||
} | ||
if (typeof field === "string" && field in fields) { | ||
return fields[field]; | ||
} | ||
return COMPONENT_TYPES[schema.type] || _UnsupportedField2["default"]; | ||
} | ||
function getLabel(label, required) { | ||
@@ -112,5 +123,6 @@ if (!label) { | ||
var definitions = registry.definitions; | ||
var fields = registry.fields; | ||
var schema = (0, _utils.retrieveSchema)(props.schema, definitions); | ||
var FieldComponent = COMPONENT_TYPES[schema.type] || _UnsupportedField2["default"]; | ||
var FieldComponent = getFieldComponent(schema, uiSchema, fields); | ||
@@ -149,3 +161,6 @@ if (Object.keys(schema).length === 0) { | ||
uiSchema: _react.PropTypes.object, | ||
registry: _react.PropTypes.object | ||
registry: _react.PropTypes.shape({ | ||
widgets: _react.PropTypes.objectOf(_react.PropTypes.func).isRequired, | ||
fields: _react.PropTypes.objectOf(_react.PropTypes.func).isRequired | ||
}) | ||
}; | ||
@@ -152,0 +167,0 @@ } |
@@ -143,5 +143,12 @@ "use strict"; | ||
value: function getRegistry() { | ||
// For BC, accept passed SchemaField and TitleField props and pass them to | ||
// the "fields" registry one. | ||
var _SchemaField = this.props.SchemaField || _fieldsSchemaField2["default"]; | ||
var _TitleField = this.props.TitleField || _fieldsTitleField2["default"]; | ||
var fields = Object.assign({ | ||
SchemaField: _SchemaField, | ||
TitleField: _TitleField | ||
}, this.props.fields); | ||
return { | ||
SchemaField: this.props.SchemaField || _fieldsSchemaField2["default"], | ||
TitleField: this.props.TitleField || _fieldsTitleField2["default"], | ||
fields: fields, | ||
widgets: this.props.widgets || {}, | ||
@@ -158,7 +165,6 @@ definitions: this.props.schema.definitions || {} | ||
var uiSchema = _props.uiSchema; | ||
var widgets = _props.widgets; | ||
var formData = this.state.formData; | ||
var registry = this.getRegistry(); | ||
var _SchemaField = registry.SchemaField; | ||
var _SchemaField = registry.fields.SchemaField; | ||
return _react2["default"].createElement( | ||
@@ -172,3 +178,2 @@ "form", | ||
formData: formData, | ||
widgets: widgets, | ||
onChange: this._onChange, | ||
@@ -199,8 +204,7 @@ registry: registry }), | ||
formData: _react.PropTypes.any, | ||
widgets: _react.PropTypes.object, | ||
widgets: _react.PropTypes.objectOf(_react.PropTypes.func), | ||
fields: _react.PropTypes.objectOf(_react.PropTypes.func), | ||
onChange: _react.PropTypes.func, | ||
onError: _react.PropTypes.func, | ||
onSubmit: _react.PropTypes.func, | ||
SchemaField: _react.PropTypes.func, | ||
TitleField: _react.PropTypes.func | ||
onSubmit: _react.PropTypes.func | ||
}; | ||
@@ -207,0 +211,0 @@ } |
{ | ||
"name": "react-jsonschema-form", | ||
"version": "0.16.2", | ||
"version": "0.17.0", | ||
"description": "A simple React component capable of building HTML forms out of a JSON schema.", | ||
@@ -5,0 +5,0 @@ "scripts": { |
230
README.md
@@ -16,3 +16,4 @@ react-jsonschema-form | ||
- [Usage](#usage) | ||
- [Custom labels for enum fields](#custom-labels-for-enum-fields) | ||
- [Form customization](#form-customization) | ||
- [The uiSchema object](#the-uischema-object) | ||
- [Alternative widgets](#alternative-widgets) | ||
@@ -22,13 +23,17 @@ - [For boolean fields](#for-boolean-fields) | ||
- [For number and integer fields](#for-number-and-integer-fields) | ||
- [Object fields ordering](#object-fields-ordering) | ||
- [Multiple choices list](#multiple-choices-list) | ||
- [Custom styles](#custom-styles) | ||
- [Custom widgets](#custom-widgets) | ||
- [Custom SchemaField](#custom-schemafield) | ||
- [Custom titles](#custom-titles) | ||
- [Custom buttons](#custom-buttons) | ||
- [Schema definitions & references](#schema-definitions-references) | ||
- [Development server](#development-server) | ||
- [Tests](#tests) | ||
- [TDD](#tdd) | ||
- [Object fields ordering](#object-fields-ordering) | ||
- [Custom CSS class names](#custom-css-class-names) | ||
- [Custom labels for enum fields](#custom-labels-for-enum-fields) | ||
- [Multiple choices list](#multiple-choices-list) | ||
- [Form action buttons](#form-action-buttons) | ||
- [Advanced customization](#advanced-customization) | ||
- [Custom widget components](#custom-widget-components) | ||
- [Custom field components](#custom-field-components) | ||
- [Custom SchemaField](#custom-schemafield) | ||
- [Custom titles](#custom-titles) | ||
- [Schema definitions and references](#schema-definitions-and-references) | ||
- [Contributing](#contributing) | ||
- [Development server](#development-server) | ||
- [Tests](#tests) | ||
- [TDD](#tdd) | ||
- [License](#license) | ||
@@ -102,29 +107,40 @@ | ||
### Custom labels for `enum` fields | ||
## Form customization | ||
This library supports the [enumNames](https://github.com/json-schema/json-schema/wiki/enumNames-%28v5-proposal%29) property, which allows defining custom labels for each option of an `enum`: | ||
### The `uiSchema` object | ||
JSONSchema is limited for describing how a given data type should be rendered as a form input component, that's why this lib introduces the concept of *UI schema*. | ||
A UI schema is basically an object literal providing information on **how** the form should be rendered, while the JSON schema tells **what**. | ||
The uiSchema object follows the tree structure of the form field hierarchy, and for each allows to define how it should be rendered: | ||
```js | ||
const schema = { | ||
type: "number", | ||
enum: [1, 2, 3], | ||
enumNames: ["one", "two", "three"] | ||
}; | ||
``` | ||
type: "object", | ||
properties: { | ||
foo: { | ||
type: "object", | ||
properties: { | ||
bar: {type: "string"} | ||
} | ||
} | ||
} | ||
} | ||
This will be rendered using a select box that way: | ||
const uiSchema = { | ||
foo: { | ||
bar: { | ||
"ui:widget": "textarea" | ||
} | ||
} | ||
} | ||
```html | ||
<select> | ||
<option value="1">one</option> | ||
<option value="2">two</option> | ||
<option value="3">three</option> | ||
</select> | ||
render(<Form schema={schema} uiSchema={formData} />, | ||
document.getElementById("app")); | ||
``` | ||
Note that string representations of numbers will be cast back and reflected as actual numbers into form state. | ||
### Alternative widgets | ||
JSONSchema is limited for describing how a given data type should be rendered as an input component, that's why this lib introduces the concept of *UI schema*. A UI schema is basically an object literal describing how the form should be rendered, eg. which UI widget should be used to render a certain field thanks to the `ui:widget` property: | ||
The uiSchema `ui:widget` property tells the form which UI widget should be used to render a certain field: | ||
@@ -169,3 +185,3 @@ Example: | ||
## Object fields ordering | ||
### Object fields ordering | ||
@@ -192,12 +208,6 @@ The `uiSchema` object spec also allows you to define in which order a given object field properties should be rendered using the `ui:order` property: | ||
## Multiple choices list | ||
### Custom CSS class names | ||
The default behavior for array fields is a list of text inputs with add/remove buttons. If you want a multiple choices list, you have to provide an `enum` list to the `items` property of the array field and set `uniqueItems` property to `true`. | ||
The uiSchema object accepts a `classNames` property for each field of the schema: | ||
See the "Arrays" section of the demo app and [this issue](https://github.com/mozilla-services/react-jsonschema-form/issues/41) for more information. | ||
## Custom styles | ||
The UISchema object accepts a `classNames` property for each field of the schema: | ||
```jsx | ||
@@ -222,4 +232,57 @@ const uiSchema = { | ||
## Custom widgets | ||
### Custom labels for `enum` fields | ||
This library supports the [`enumNames`](https://github.com/json-schema/json-schema/wiki/enumNames-%28v5-proposal%29) property for `enum` fields, which allows defining custom labels for each option of an `enum`: | ||
```js | ||
const schema = { | ||
type: "number", | ||
enum: [1, 2, 3], | ||
enumNames: ["one", "two", "three"] | ||
}; | ||
``` | ||
This will be rendered using a select box that way: | ||
```html | ||
<select> | ||
<option value="1">one</option> | ||
<option value="2">two</option> | ||
<option value="3">three</option> | ||
</select> | ||
``` | ||
Note that string representations of numbers will be cast back and reflected as actual numbers into form state. | ||
### Multiple choices list | ||
The default behavior for array fields is a list of text inputs with add/remove buttons. If you want a multiple choices list, you have to provide an `enum` list to the `items` property of the array field and set `uniqueItems` property to `true`. | ||
See the "Arrays" section of the demo app and [this issue](https://github.com/mozilla-services/react-jsonschema-form/issues/41) for more information. | ||
### Form action buttons | ||
You can provide custom buttons to your form via the `Form` component's `children`. A default submit button will be rendered if you don't provide children to the `Form` component. | ||
```jsx | ||
render( | ||
<Form schema={schema}> | ||
<div> | ||
<button type="submit">Submit</button> | ||
<button>Cancel</button> | ||
</div> | ||
</Form>); | ||
``` | ||
**Warning:** there should be a button or an input with `type="submit"` to trigger the form submission (and then the form validation). | ||
## Advanced customization | ||
The API allows to specify your own custom *widgets* and *fields* 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. | ||
### Custom widget components | ||
You can provide your own custom widgets to a uiSchema for the following json data types: | ||
@@ -294,4 +357,63 @@ | ||
## Custom SchemaField | ||
### Custom field components | ||
You can provide your own field components to a uiSchema for basically any json schema data type, by specifying a `ui:field` property. | ||
For example, let's create and register a dumb `geo` component handling a *latitude* and a *longitude*: | ||
```jsx | ||
const schema = { | ||
type: "object", | ||
required: ["lat", "lon"], | ||
properties: { | ||
lat: {type: "number"}, | ||
lon: {type: "number"} | ||
} | ||
}; | ||
// Define a custom component for handling the root position object | ||
class GeoPosition extends React.Component { | ||
constructor(props) { | ||
super(props); | ||
this.state = {...props.formData}; | ||
} | ||
onChange(name) { | ||
return (event) => { | ||
this.setState({ | ||
[name]: parseFloat(event.target.value) | ||
}, () => this.props.onChange(this.state)); | ||
}; | ||
} | ||
render() { | ||
const {lat, lon} = this.state; | ||
return ( | ||
<div> | ||
<input type="number" value={lat} onChange={this.onChange("lat")} /> | ||
<input type="number" value={lon} onChange={this.onChange("lon")} /> | ||
</div> | ||
); | ||
} | ||
} | ||
// Define the custom field component to use for the root object | ||
const uiSchema = {"ui:field": "geo"}; | ||
// Define the custom field components to register; here our "geo" | ||
// custom field component | ||
const fields = {geo: GeoPosition}; | ||
// Render the form with all the properties we just defined passed | ||
// as props | ||
render(<Form | ||
schema={schema} | ||
uiSchema={uiSchema} | ||
fields={fields}/>); | ||
``` | ||
Note: Registered fields can be reused accross the entire schema. | ||
### Custom SchemaField | ||
**Warning:** This is a powerful feature as you can override the whole form behavior and easily mess it up. Handle with care. | ||
@@ -325,3 +447,3 @@ | ||
## Custom titles | ||
### Custom titles | ||
@@ -345,20 +467,4 @@ You can provide your own implementation of the `TitleField` base React component for rendering any title. This is useful when you want to augment how titles are handled. | ||
## Custom buttons | ||
## Schema definitions and references | ||
You can provide custom buttons to your form via the `Form` component's `children`. A default submit button will be rendered if you don't provide children to the `Form` component. | ||
```jsx | ||
render( | ||
<Form schema={schema}> | ||
<div> | ||
<button type="submit">Submit</button> | ||
<button>Cancel</button> | ||
</div> | ||
</Form>); | ||
``` | ||
**Warning:** there should be a button or an input with `type="submit"` to trigger the form submission (and then the form validation). | ||
## Schema definitions & references | ||
This library partially supports [inline schema definition dereferencing]( http://json-schema.org/latest/json-schema-core.html#rfc.section.7.2.3), which is Barbarian for *avoiding to copy and paste commonly used field schemas*: | ||
@@ -391,4 +497,6 @@ | ||
## Development server | ||
## Contributing | ||
### Development server | ||
``` | ||
@@ -400,3 +508,3 @@ $ npm start | ||
## Tests | ||
### Tests | ||
@@ -407,3 +515,3 @@ ``` | ||
### TDD | ||
#### TDD | ||
@@ -410,0 +518,0 @@ ``` |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
676194
1860
513