Skip to content

Commit b922ace

Browse files
committed
Fixed josdejong#285: an issue with the enum drop down when having defined multiple enums in a JSON schema
1 parent 60b7b17 commit b922ace

File tree

2 files changed

+54
-46
lines changed

2 files changed

+54
-46
lines changed

HISTORY.md

+6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
https://github.com/josdejong/jsoneditor
44

55

6+
## 2016-05-22, version 5.5.4
7+
8+
- Fixed #285: an issue with the enum drop down when having defined multiple
9+
enums in a JSON schema.
10+
11+
612
## 2016-05-22, version 5.5.3
713

814
- Fixed #299: reverted the fix of #268 by trimming text in fields and values.

src/js/Node.js

+48-46
Original file line numberDiff line numberDiff line change
@@ -1277,10 +1277,10 @@ Node.prototype._updateDomValue = function () {
12771277
this.dom.select.appendChild(this.dom.select.option);
12781278

12791279
//Iterate all enum values and add them as options
1280-
for(var i = 0; i < this.enum.enum.length; i++) {
1280+
for(var i = 0; i < this.enum.length; i++) {
12811281
this.dom.select.option = document.createElement('option');
1282-
this.dom.select.option.value = this.enum.enum[i];
1283-
this.dom.select.option.innerHTML = this.enum.enum[i];
1282+
this.dom.select.option.value = this.enum[i];
1283+
this.dom.select.option.innerHTML = this.enum[i];
12841284
if(this.dom.select.option.value == this.value){
12851285
this.dom.select.option.selected = true;
12861286
}
@@ -1983,59 +1983,61 @@ Node.prototype.updateDom = function (options) {
19831983
Node.prototype._updateSchema = function () {
19841984
//Locating the schema of the node and checking for any enum type
19851985
if(this.editor && this.editor.options) {
1986-
var field = (this.index != undefined) ? this.index : this.field;
1987-
1988-
//Search for the schema element of the current node and store it in the schema attribute.
1989-
//Hereafter, wherever you have access in the node you will have also access in its own schema.
1990-
this.schema = this._getJsonObject(this.editor.options.schema, 'name', field)[0];
1991-
if(!this.schema) {
1992-
this.schema = this._getJsonObject(this.editor.options.schema, field)[0];
1993-
}
1994-
1995-
//Search for any enumeration type in the schema of the current node.
1996-
//Enum types can be also be part of a composite type.
1997-
if(this.schema){
1998-
if(this.schema.hasOwnProperty('enum')){
1999-
this.enum = {};
2000-
this.enum.enum = this.schema.enum;
2001-
} else if(this.schema.hasOwnProperty('oneOf')){
2002-
this.enum = this._getJsonObject(this.schema.oneOf, 'enum')[0];
2003-
} else if(this.schema.hasOwnProperty('anyOf')){
2004-
this.enum = this._getJsonObject(this.schema.anyOf, 'enum')[0];
2005-
} else if(this.schema.hasOwnProperty('allOf')){
2006-
this.enum = this._getJsonObject(this.schema.allOf, 'enum')[0];
2007-
} else {
2008-
delete this.enum;
2009-
}
2010-
} else {
1986+
// find the part of the json schema matching this nodes path
1987+
this.schema = Node._findSchema(this.editor.options.schema, this.getPath());
1988+
if (this.schema) {
1989+
this.enum = Node._findEnum(this.schema);
1990+
}
1991+
else {
20111992
delete this.enum;
20121993
}
20131994
}
20141995
};
20151996

20161997
/**
2017-
* Get all sub-elements of the given object with the specified key and value.
1998+
* find an enum definition in a JSON schema, as property `enum` or inside
1999+
* one of the schemas composites (`oneOf`, `anyOf`, `allOf`)
2000+
* @param {Object} schema
2001+
* @return {Array | null} Returns the enum when found, null otherwise.
20182002
* @private
20192003
*/
2020-
Node.prototype._getJsonObject = function (obj, key, val) {
2021-
var objects = [];
2022-
for (var i in obj) {
2023-
if (!obj.hasOwnProperty(i)) continue;
2024-
if (typeof obj[i] == 'object') {
2025-
if(i === key && val === undefined){
2026-
if(Array.isArray(obj[i])) {
2027-
objects.push(obj);
2028-
} else {
2029-
objects.push(obj[i]);
2030-
}
2031-
} else {
2032-
objects = objects.concat(this._getJsonObject(obj[i], key, val));
2033-
}
2034-
} else if (i == key && obj[key] == val) {
2035-
objects.push(obj);
2004+
Node._findEnum = function (schema) {
2005+
if (schema.enum) {
2006+
return schema.enum;
2007+
}
2008+
2009+
var composite = schema.oneOf || schema.anyOf || schema.allOf;
2010+
if (composite) {
2011+
var match = composite.filter(function (entry) {return entry.enum});
2012+
if (match.length > 0) {
2013+
return match[0].enum;
2014+
}
2015+
}
2016+
2017+
return null
2018+
};
2019+
2020+
/**
2021+
* Return the part of a JSON schema matching given path.
2022+
* @param {Object} schema
2023+
* @param {Array.<string | number>} path
2024+
* @return {Object | null}
2025+
* @private
2026+
*/
2027+
Node._findSchema = function (schema, path) {
2028+
var childSchema = schema;
2029+
2030+
for (var i = 0; i < path.length && childSchema; i++) {
2031+
var key = path[i];
2032+
if (typeof key === 'string' && childSchema.properties) {
2033+
childSchema = childSchema.properties[key] || null
2034+
}
2035+
else if (typeof key === 'number' && childSchema.items) {
2036+
childSchema = childSchema.items
20362037
}
20372038
}
2038-
return objects;
2039+
2040+
return childSchema
20392041
};
20402042

20412043
/**

0 commit comments

Comments
 (0)