This JavaScript library will
- generate a form from a given JSON Schema,
- fill (that) form with a JSON data structure contained in a (hidden) textarea,
- sync changes to the form to the data structure, and
- display validation errors in the form if the data structure fails to validate against the schema.
The combination of these features allows for the rapid development of instant user interfaces for JSON APIs, e.g. in CouchDB powered back office GUIs.
You can view a demo at http://p7s1digital.github.com/json-schema-component/demo.html
Here is a simple example showing how to embed this library in your web application:
<!-- .. --> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"> <script src="http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"> <script src="path/to/JsonSchemaComponent.js"> <script> new JsonSchemaComponent({ schema: { properties: { eaten_by_whale: { description: "Has this thing been eaten by a whale ?", type: "boolean" } } }, textarea: $('#mytextarea'), form: $('#myform') }); $('#mytextarea').hide() </script> </body> </html>
You need to include jQuery (tested with 1.7.1) and
jQuery.tmpl before including
JsonSchemaComponent.js
. If you also want to support browsers without
native JSON support, you need to include Douglas Crockford's json2.js.
This is a complete list of the properties new JsonSchemaComponent({/*
properties here*/});
accepts:
- schema <object> (required)
- JavaScript object containing the JSON Schema that is used to generate the form.
- textarea <selector or jQuery> (required)
- The textarea containing the JSON data structure that is kept in sync with the form. The value of the textarea must be valid JSON.
- form <selector or jQuery> (required if existing_form not specified)
- The DOM node where the form should be generated.
- existing_form <selector or jQuery> (required if form not specified)
- If you want to render the form on the server side (or client-side before invoking JsonSchemaComponent) you can specify a form that is already in the DOM. JsonSchemaComponent will then only attach event handlers to update it.
- template <string> (optional)
- The jquery.tmpl template used to generate the form using the schema. The default template will be used if omitted.
- validation_errors_formatter <function> (optional)
- A function that translates or formats JSV validation reports. Defaults to
function(errors) {return errors;}
. - split_tags_by <RegExp> (optional)
- For fields with type
array
but without predefineditems
, use this as a list separator. Defaults to/,\ */
.
You can use garycourt's JSV to validate
the user's form input against the given schema. JsonSchemaComponent will detect
if JSV was loaded (please make sure to load uri.js
, jsv.js
and e.g.
json-schema-draft-03.js
) and will start validating automatically.
If there is a validation error, the containing form will get the CSS class
error
.
For each field that fails to validate the JsonSchemaComponent will look for an
element with the id fieldname-error (so, e.g. eaten_by_whale-error
for
the property in the introductory example) in the form (independent of whether
it's provided or generated by a template) and display the error message there.
If there is no such element, one will be generated and used at validation time.
Because it might be beneficial to know when the form validates or not,
JsonSchemaComponent fires custom jQuery events (validates
and errors
,
respectively) on the form element every time the validation status changes.
Here is an example on how to use that to disable the submit button as long as the form does not validate:
var myform = $("#myform"); var mycomponent = new JsonSchemaComponent({ schema : /* .. */, textarea : /* .. */, form : myform }); myform.on("validates", function() { myform.find("input[type=submit]").removeAttr("disabled"); }); myform.on("errors", function(errors) { // do something with the errors myform.find("input[type=submit]").attr("disabled", "disabled"); });
If you want to (instead of or in addition to client side validation) want to
display server side validation errors, you can do so by feeding a JSV error
report compatible JavaScript object to setValidationErrors
like this:
var mycomponent = new JsonSchemaComponent({ schema : /* .. */, textarea : /* .. */, form : /* .. */ }); // this could be from ajax var backend_error_report = [{ message : "But what's this long face about, Mr. Starbuck; wilt thou not chase the white whale!", details : "no specific reason", uri : "/title", }] mycomponent.setValidationErrors(backend_error_report);
You can learn more about JSV's Report format at the "Example" section of it's documentation.
If you want to translate JSV's (or your server's) validation errors to your
mother tongue, you can specify a translating function as the
validation_errors_formatter
parameter at construction time like this:
var mycomponent = new JsonSchemaComponent({ schema : /* .. */, textarea : /* .. */, form : /* .. */, validation_errors_formatter: function(errors) { /* Translate error messages to german */ return $.map(errors, function(error) { if (error.message === "The number of items is greater then the required maximum") { error.message = "Die Anzahl der Einträge ist größer als das erforderliche Maximum" } return error; }); } });
The array errors
fed to the validation_errors_formatter
function is in
the same form as JSV's error report and the same as mentioned above. Errors set
via setValidationErrors
are also piped through this function.
Although this library performs validation, you need to apply some validation on the server side before saving the user-provided data to your database for security reasons.
All form input elements created by JsonSchemaComponent adhere to the coming
HTML5 forms standard. That is, fields for dates get <input type=datetime />
markup, etc. If the browsers of your target audience support that, you should
be fine.
If you want to integrate a JsonSchemaComponent with your GUI toolkit, you can augment and attach event handlers to the form after it has been rendered.
However, since - at the time of writing - not all browsers support all HTML5 form features, here's how to use WEBSHIMS LIB.'s form-ext module to attach fallback widgets for legacy browsers:
<!-- ... --> <script src="http://afarkas.github.com/webshim/demos/js-webshim/minified/extras/modernizr-custom.js"></script> <script src="http://afarkas.github.com/webshim/demos/js-webshim/minified/polyfiller.js"></script> <script src="path/to/JsonSchemaComponent.js"> $.webshims.polyfill('forms-ext'); $.webshims.ready('forms-ext', function() { var mycomponent = new JsonSchemaComponent({ schema: { properties: { arrival: { description: "Favorite time of day", type: "date" } } }, textarea: /* .. */, form: $("#myform"), }); });
If you want to use both validation via JSV and WEBSHIMS LIB. on the same side, there is a namespace clash you need to work around. You first need to load JSV, then delete the window.require property, then load WEBSHIMS LIB. like this:
<script src=vendor/uri.js></script> <script src=vendor/jsv.js></script> <script src=vendor/json-schema-draft-03.js></script> <script> /* the three modules above create a non-standard 'window.require' object, that makes the following two libraries trip when loading additional modules */ delete window.require; </script> <script src="http://afarkas.github.com/webshim/demos/js-webshim/minified/extras/modernizr-custom.js"></script> <script src="http://afarkas.github.com/webshim/demos/js-webshim/minified/polyfiller.js"></script>
If you use your own AMD loader (e.g. requirejs) these steps should not be neccessary. You could also use a patched version of the JSV files.
JsonSchemaComponent creates a
datalist element for every
field in the form you generate to allow autocompletion (think "Google
Suggest"). Changing the suggestion list is as easy as appending option
elements to a select
element:
mycomponent.setDatalist('author', '<option value="melville">Herman Melville</option>' + '<option value="shakespeare">William Shakespeare</option>');
(The first argument of setDatalist
is the property name of the field the
datalist is about, the second argument is a string of html containing option
elements with suggestions.)
In modern browsers supporting datalist this should offer an instant autocomplete list; If you use the WEBSHIMS LIB. as described above you will get this functionality also in older browsers.
The demo page included in the repository has an example on how to use Ajax to load the suggestion list.
To hack on this library itself (not for using this as part of your web application), you need to clone the source code repository from GitHub like this:
git clone https://github.com/p7s1digital/json-schema-component.git cd json-schema-component
JsonSchemaComponent comes with optional AMD loader compatibilty and can be required as "JsonSchemaComponent". The only hard dependency is jQuery, please make sure all optional dependencies are present.
Testing this library is done using Jasmine BDD. You can find the test suite in
src/JsonSchemaComponent.specs.js
and execute the tests in your browser at
http://p7s1digital.github.com/json-schema-component/tests.html.
At the moment we know the tests work in Google Chrome, Safari, Firefox 9 and Internet Explorer 9.
We use GitHub Issues to track defects and feature requests at
https://github.com/p7s1digital/json-schema-component/issues. To demonstrate a
certain behavior, you can link to the demo page (the state
of the input values is persisted in the hash part ("#preset=
") of the url).
Please use an URL shortening service when posting such
URLs to the issue tracker.
This library does not (yet) support the complete JSON Schema specification. Pull requests containing tests are welcome!
- (unreleased)
- support array types w/o items specified in schema in a comma separated text field
- add validation_errors_formatter
- replace setValidationReport w/ setValidationErrors (former will be deprecated soon)
- support autocomplete via datalist
- support advanced HTML5 widgets via WEBSHIMS LIB.
- (optionally) registers as AMD module "JsonSchemaComponent"
- support type=number and type=integer
- gracefully render <input type=text> for type attributes not explicitly supported
- ignore changes to inputs that are not in the schema
- v0.2 - 2012-01-31
- add validation
- v0.1 - 2012-01-03
- initial, non-public release
Copyright (c) 2013 ProSiebenSat.1 Digital GmbH Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- Authors
- Filip Noetzel, Lovely Systems, Dornbirn