add support for json schema references ($ref)
This commit is contained in:
parent
3a8aa1755c
commit
b77deb969c
19
docs/api.md
19
docs/api.md
|
@ -102,6 +102,11 @@ Constructs a new JSONEditor.
|
||||||
|
|
||||||
See [http://json-schema.org/](http://json-schema.org/) for more information.
|
See [http://json-schema.org/](http://json-schema.org/) for more information.
|
||||||
|
|
||||||
|
- `{Object} schemaRefs`
|
||||||
|
|
||||||
|
Schemas that are referenced using the `$ref` property from the JSON schema that are set in the `schema` option,
|
||||||
|
the object structure in the form of `{reference_key: schemaObject}`
|
||||||
|
|
||||||
- `{boolean} search`
|
- `{boolean} search`
|
||||||
|
|
||||||
Enables a search box in the upper right corner of the JSONEditor. True by default. Only applicable when `mode` is 'tree', 'view', or 'form'.
|
Enables a search box in the upper right corner of the JSONEditor. True by default. Only applicable when `mode` is 'tree', 'view', or 'form'.
|
||||||
|
@ -234,6 +239,20 @@ See [http://json-schema.org/](http://json-schema.org/) for more information on t
|
||||||
|
|
||||||
A JSON schema.
|
A JSON schema.
|
||||||
|
|
||||||
|
#### `JSONEditor.setSchemaRef(schema, ref)`
|
||||||
|
|
||||||
|
Set a schema that are referenced from the schema that are set on the `schema` option. See also option `schemaRefs`.
|
||||||
|
|
||||||
|
*Parameters:*
|
||||||
|
|
||||||
|
- `{Object} schema`
|
||||||
|
|
||||||
|
A JSON schema.
|
||||||
|
|
||||||
|
- `{String} ref`
|
||||||
|
|
||||||
|
The reference key.
|
||||||
|
|
||||||
#### `JSONEditor.setText(jsonString)`
|
#### `JSONEditor.setText(jsonString)`
|
||||||
|
|
||||||
Set text data in the editor.
|
Set text data in the editor.
|
||||||
|
|
|
@ -47,20 +47,41 @@
|
||||||
"description": "Age in years",
|
"description": "Age in years",
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"minimum": 0
|
"minimum": 0
|
||||||
|
},
|
||||||
|
"job": {
|
||||||
|
"$ref": "job"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["firstName", "lastName"]
|
"required": ["firstName", "lastName"]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var job = {
|
||||||
|
"title": "Job description",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"company": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var json = {
|
var json = {
|
||||||
firstName: 'John',
|
firstName: 'John',
|
||||||
lastName: 'Doe',
|
lastName: 'Doe',
|
||||||
gender: null,
|
gender: null,
|
||||||
age: 28
|
age: 28,
|
||||||
|
job: {
|
||||||
|
company: 'freelance',
|
||||||
|
role: 'developer'
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
schema: schema
|
schema: schema,
|
||||||
|
schemaRefs: {"job": job}
|
||||||
};
|
};
|
||||||
|
|
||||||
// create the editor
|
// create the editor
|
||||||
|
|
|
@ -79,7 +79,7 @@ function JSONEditor (container, options, json) {
|
||||||
// validate options
|
// validate options
|
||||||
if (options) {
|
if (options) {
|
||||||
var VALID_OPTIONS = [
|
var VALID_OPTIONS = [
|
||||||
'ajv', 'schema','templates',
|
'ajv', 'schema', 'schemaRefs','templates',
|
||||||
'ace', 'theme','autocomplete',
|
'ace', 'theme','autocomplete',
|
||||||
'onChange', 'onEditable', 'onError', 'onModeChange',
|
'onChange', 'onEditable', 'onError', 'onModeChange',
|
||||||
'escapeUnicode', 'history', 'search', 'mode', 'modes', 'name', 'indentation', 'sortObjectKeys'
|
'escapeUnicode', 'history', 'search', 'mode', 'modes', 'name', 'indentation', 'sortObjectKeys'
|
||||||
|
@ -269,6 +269,40 @@ JSONEditor.prototype._onError = function(err) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns ajv instance, initiates if not exists
|
||||||
|
* @returns {Object} ajv
|
||||||
|
*/
|
||||||
|
JSONEditor.prototype._getAjvInstance = function () {
|
||||||
|
if (!this.ajv) {
|
||||||
|
try {
|
||||||
|
// grab ajv from options if provided, else create a new instance
|
||||||
|
this.ajv = this.options.ajv || Ajv({ allErrors: true, verbose: true });
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.warn('Failed to create an instance of Ajv, JSON Schema validation is not available. Please use a JSONEditor bundle including Ajv, or pass an instance of Ajv as via the configuration option `ajv`.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.ajv;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set reference schema object for schema which is depended with other schemas using <pre><code>$ref</code></pre>
|
||||||
|
* @param {Object} schema Schema object
|
||||||
|
* @param {String} ref reference key
|
||||||
|
*/
|
||||||
|
JSONEditor.prototype.setSchemaRef = function (schema, ref) {
|
||||||
|
if (schema && ref) {
|
||||||
|
var ajv = this._getAjvInstance();
|
||||||
|
|
||||||
|
if (ajv) {
|
||||||
|
ajv.removeSchema(ref);
|
||||||
|
ajv.addSchema(schema, ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a JSON schema for validation of the JSON object.
|
* Set a JSON schema for validation of the JSON object.
|
||||||
* To remove the schema, call JSONEditor.setSchema(null)
|
* To remove the schema, call JSONEditor.setSchema(null)
|
||||||
|
@ -277,15 +311,7 @@ JSONEditor.prototype._onError = function(err) {
|
||||||
JSONEditor.prototype.setSchema = function (schema) {
|
JSONEditor.prototype.setSchema = function (schema) {
|
||||||
// compile a JSON schema validator if a JSON schema is provided
|
// compile a JSON schema validator if a JSON schema is provided
|
||||||
if (schema) {
|
if (schema) {
|
||||||
var ajv;
|
var ajv = this._getAjvInstance();
|
||||||
try {
|
|
||||||
// grab ajv from options if provided, else create a new instance
|
|
||||||
ajv = this.options.ajv || Ajv({ allErrors: true, verbose: true });
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
console.warn('Failed to create an instance of Ajv, JSON Schema validation is not available. Please use a JSONEditor bundle including Ajv, or pass an instance of Ajv as via the configuration option `ajv`.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ajv) {
|
if (ajv) {
|
||||||
this.validateSchema = ajv.compile(schema);
|
this.validateSchema = ajv.compile(schema);
|
||||||
|
|
|
@ -220,6 +220,12 @@ textmode.create = function (container, options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.options.schemaRefs) {
|
||||||
|
for (var ref in this.options.schemaRefs) {
|
||||||
|
this.setSchemaRef(this.options.schemaRefs[ref], ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.setSchema(this.options.schema);
|
this.setSchema(this.options.schema);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,7 @@ treemode._setOptions = function (options) {
|
||||||
mode: 'tree',
|
mode: 'tree',
|
||||||
name: undefined, // field name of root node
|
name: undefined, // field name of root node
|
||||||
schema: null,
|
schema: null,
|
||||||
|
schemaRefs: null,
|
||||||
autocomplete: null
|
autocomplete: null
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -124,6 +125,13 @@ treemode._setOptions = function (options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set schema refs before schema compile, is available
|
||||||
|
if (this.options.schemaRefs) {
|
||||||
|
for (var ref in this.options.schemaRefs) {
|
||||||
|
this.setSchemaRef(this.options.schemaRefs[ref], ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// compile a JSON schema validator if a JSON schema is provided
|
// compile a JSON schema validator if a JSON schema is provided
|
||||||
this.setSchema(this.options.schema);
|
this.setSchema(this.options.schema);
|
||||||
|
|
||||||
|
|
|
@ -57,22 +57,27 @@
|
||||||
"minimum": 0
|
"minimum": 0
|
||||||
},
|
},
|
||||||
"hobbies": {
|
"hobbies": {
|
||||||
"type": "array",
|
"$ref": "hobbies.json"
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["firstName", "lastName"]
|
"required": ["firstName", "lastName"]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var hobbiesSchema = {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
mode: 'tree',
|
mode: 'tree',
|
||||||
modes: ['code', 'form', 'text', 'tree', 'view'], // allowed modes
|
modes: ['code', 'form', 'text', 'tree', 'view'], // allowed modes
|
||||||
onError: function (err) {
|
onError: function (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
},
|
},
|
||||||
schema: schema
|
schema: schema,
|
||||||
|
schemaRefs: {"hobbies.json": hobbiesSchema}
|
||||||
};
|
};
|
||||||
|
|
||||||
var json = {
|
var json = {
|
||||||
|
|
Loading…
Reference in New Issue