diff --git a/README.md b/README.md index cfd4077179..23b4eddfae 100644 --- a/README.md +++ b/README.md @@ -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) @@ -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 +
+``` + ## 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*: diff --git a/package.json b/package.json index 883da01b38..9d0aa8bcdc 100644 --- a/package.json +++ b/package.json @@ -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": { diff --git a/playground/app.js b/playground/app.js index 4757b35fb2..364d3d442a 100644 --- a/playground/app.js +++ b/playground/app.js @@ -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", }, }; diff --git a/playground/samples/bootstrap.js b/playground/samples/bootstrap.js new file mode 100644 index 0000000000..4409c4623c --- /dev/null +++ b/playground/samples/bootstrap.js @@ -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", + }, +}; diff --git a/playground/samples/customArray.js b/playground/samples/customArray.js index ebd7f3e32d..ab984cb368 100644 --- a/playground/samples/customArray.js +++ b/playground/samples/customArray.js @@ -4,7 +4,7 @@ function ArrayFieldTemplate(props) { return (+ Invalid {name || "root"} object field configuration: + {err.message}. +
+{JSON.stringify(schema)}+