Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Easier Bootstrap Grid usage and basic BS4 compatibility #623

Closed
wants to merge 9 commits into from
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ A [live playground](https://mozilla-services.github.io/react-jsonschema-form/) i
- [Error List Display](#error-list-display)
- [The case of empty strings](#the-case-of-empty-strings)
- [Styling your forms](#styling-your-forms)
- [Bootstrap Field Groups](#bootstrap-field-groups)
- [Schema definitions and references](#schema-definitions-and-references)
- [JSON Schema supporting status](#json-schema-supporting-status)
- [Tips and tricks](#tips-and-tricks)
Expand Down Expand Up @@ -1370,6 +1371,54 @@ Here are some examples from the [playground](http://mozilla-services.github.io/r

Last, if you really really want to override the semantics generated by the lib, you can always create and use your own custom [widget](#custom-widget-components), [field](#custom-field-components) and/or [schema field](#custom-schemafield) components.

## Bootstrap Field Groups

As an additional helper for bootstrap users, we have implemented a special "object" group `"bootstrap"`

By using the `bootstrap` object all nested fields will be wrapped in a `"row"` div for easier column creation. Additionally any fields that do not have a `col-xs-*` className added will have `col-xs-12` added to them.

```js
const schema = {
type: "bootstrap",
title: "My Form Group",
properties: {
foo: {type: "string"},
bar: {type: "string"}
}
};

const uiSchema = {
foo: {
classNames: "col-md-6"
},
bar: {
classNames: "col-xs-4 col-md-6"
}
};
```

will result in

```html
<fieldset>
<legend>My Form Group</legend>
<div class="row">
<div class="field field-string col-xs-12 col-md-6">
<label>
<span>foo</span>
<input name="foo" type="text">
</label>
</div>
<div class="field field-string col-xs-4 col-md-6">
<label>
<span>bar</span>
<input name="bar" type="text">
</label>
</div>
</div>
</fieldset>
```

## Schema definitions and 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*:
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"publish-to-gh-pages": "npm run build:playground && gh-pages --dist build/",
"publish-to-npm": "npm run build:readme && npm run dist && npm publish",
"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"
"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",
"lint-staged": {
Expand Down
57 changes: 19 additions & 38 deletions playground/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,89 +57,70 @@ const cmOptions = {
};
const themes = {
default: {
stylesheet:
"//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css",
stylesheet: "//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css",
},
cerulean: {
stylesheet:
"//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/cerulean/bootstrap.min.css",
stylesheet: "//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/cerulean/bootstrap.min.css",
},
cosmo: {
stylesheet:
"//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/cosmo/bootstrap.min.css",
stylesheet: "//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/cosmo/bootstrap.min.css",
},
cyborg: {
stylesheet:
"//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/cyborg/bootstrap.min.css",
stylesheet: "//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/cyborg/bootstrap.min.css",
editor: "blackboard",
},
darkly: {
stylesheet:
"//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/darkly/bootstrap.min.css",
stylesheet: "//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/darkly/bootstrap.min.css",
editor: "mbo",
},
flatly: {
stylesheet:
"//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/flatly/bootstrap.min.css",
stylesheet: "//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/flatly/bootstrap.min.css",
editor: "ttcn",
},
journal: {
stylesheet:
"//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/journal/bootstrap.min.css",
stylesheet: "//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/journal/bootstrap.min.css",
},
lumen: {
stylesheet:
"//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/lumen/bootstrap.min.css",
stylesheet: "//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/lumen/bootstrap.min.css",
},
paper: {
stylesheet:
"//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/paper/bootstrap.min.css",
stylesheet: "//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/paper/bootstrap.min.css",
},
readable: {
stylesheet:
"//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/readable/bootstrap.min.css",
stylesheet: "//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/readable/bootstrap.min.css",
},
sandstone: {
stylesheet:
"//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/sandstone/bootstrap.min.css",
stylesheet: "//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/sandstone/bootstrap.min.css",
editor: "solarized",
},
simplex: {
stylesheet:
"//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/simplex/bootstrap.min.css",
stylesheet: "//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/simplex/bootstrap.min.css",
editor: "ttcn",
},
slate: {
stylesheet:
"//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/slate/bootstrap.min.css",
stylesheet: "//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/slate/bootstrap.min.css",
editor: "monokai",
},
spacelab: {
stylesheet:
"//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/spacelab/bootstrap.min.css",
stylesheet: "//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/spacelab/bootstrap.min.css",
},
"solarized-dark": {
stylesheet:
"//cdn.rawgit.com/aalpern/bootstrap-solarized/master/bootstrap-solarized-dark.css",
stylesheet: "//cdn.rawgit.com/aalpern/bootstrap-solarized/master/bootstrap-solarized-dark.css",
editor: "dracula",
},
"solarized-light": {
stylesheet:
"//cdn.rawgit.com/aalpern/bootstrap-solarized/master/bootstrap-solarized-light.css",
stylesheet: "//cdn.rawgit.com/aalpern/bootstrap-solarized/master/bootstrap-solarized-light.css",
editor: "solarized",
},
superhero: {
stylesheet:
"//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/superhero/bootstrap.min.css",
stylesheet: "//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/superhero/bootstrap.min.css",
editor: "dracula",
},
united: {
stylesheet:
"//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/united/bootstrap.min.css",
stylesheet: "//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/united/bootstrap.min.css",
},
yeti: {
stylesheet:
"//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/yeti/bootstrap.min.css",
stylesheet: "//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/yeti/bootstrap.min.css",
editor: "eclipse",
},
};
Expand Down
73 changes: 73 additions & 0 deletions playground/samples/bootstrap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
module.exports = {
schema: {
title: "A Bootstrap Grid registration form",
description: "A Bootstrap Grid registration form example.",
type: "bootstrap",
required: ["firstName", "lastName"],
properties: {
firstName: {
type: "string",
title: "First name",
},
lastName: {
type: "string",
title: "Last name",
},
age: {
type: "integer",
title: "Age",
},
bio: {
type: "string",
title: "Bio",
},
password: {
type: "string",
title: "Password",
minLength: 3,
},
telephone: {
type: "string",
title: "Telephone",
minLength: 10,
},
},
},
uiSchema: {
firstName: {
classNames: "col-xs-6 col-md-4",
"ui:autofocus": true,
"ui:emptyValue": "",
},
lastName: {
classNames: "col-xs-6 col-md-4",
},
age: {
classNames: "col-md-4",
"ui:widget": "updown",
"ui:title": "Age of person",
},
bio: {
"ui:widget": "textarea",
},
password: {
"ui:widget": "password",
"ui:help": "Hint: Make it strong!",
},
date: {
"ui:widget": "alt-datetime",
},
telephone: {
"ui:options": {
inputType: "tel",
},
},
},
formData: {
firstName: "Chuck",
lastName: "Norris",
age: 75,
bio: "Roundhouse kicking asses since 1940",
password: "noneed",
},
};
4 changes: 2 additions & 2 deletions playground/samples/customArray.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ function ArrayFieldTemplate(props) {
return (
<div className={props.className}>
{props.items &&
props.items.map(element =>
props.items.map(element => (
<div key={element.index}>
<div>
{element.children}
Expand All @@ -30,7 +30,7 @@ function ArrayFieldTemplate(props) {
</button>
<hr />
</div>
)}
))}

{props.canAdd &&
<div className="row">
Expand Down
3 changes: 1 addition & 2 deletions playground/samples/date.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ module.exports = {
properties: {
native: {
title: "Native",
description:
"May not work on some browsers, notably Firefox Desktop and IE.",
description: "May not work on some browsers, notably Firefox Desktop and IE.",
type: "object",
properties: {
datetime: {
Expand Down
2 changes: 2 additions & 0 deletions playground/samples/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import arrays from "./arrays";
import bootstrap from "./bootstrap";
import nested from "./nested";
import numbers from "./numbers";
import simple from "./simple";
Expand All @@ -17,6 +18,7 @@ import alternatives from "./alternatives";

export const samples = {
Simple: simple,
bootstrap: bootstrap,
Nested: nested,
Arrays: arrays,
Numbers: numbers,
Expand Down
6 changes: 2 additions & 4 deletions playground/samples/nested.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,12 @@ module.exports = {
tasks: [
{
title: "My first task",
details:
"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
details: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
done: true,
},
{
title: "My second task",
details:
"Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur",
details: "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur",
done: false,
},
],
Expand Down
3 changes: 1 addition & 2 deletions playground/samples/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ function transformErrors(errors) {
module.exports = {
schema: {
title: "Custom validation",
description:
"This form defines custom validation rules checking that the two passwords match.",
description: "This form defines custom validation rules checking that the two passwords match.",
type: "object",
properties: {
pass1: {
Expand Down
4 changes: 2 additions & 2 deletions src/components/fields/ArrayField.js
Original file line number Diff line number Diff line change
Expand Up @@ -464,8 +464,8 @@ class ArrayField extends Component {
const itemUiSchema = additional
? uiSchema.additionalItems || {}
: Array.isArray(uiSchema.items)
? uiSchema.items[index]
: uiSchema.items || {};
? uiSchema.items[index]
: uiSchema.items || {};
const itemErrorSchema = errorSchema ? errorSchema[index] : undefined;

return this.renderArrayFieldItem({
Expand Down
Loading