Skip to content

Fixing #709 by introducing multiple_editor_select_via_property #710

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,120 @@ This can make the editor much more compact, but at a cost of not guaranteeing ch
}
```

#### Mulitple-editor (oneOf, anyOf, allOf)

When the schema uses oneOf (anyOf and allOf) the multiple-editor is used to hold the various sub-editors.
It will also try to select the correct sub-editor when using setValue to initialize the editor with data.

The default behaviour is to select the first sub-editor that has no validation-errors testing using the supplied data.

Sometimes this sub-editor-selection needs to be more specific:

When checking if a particular sub-editor is the one that should be selected,
the multiple-editor looks for an option called `multiple_editor_select_via_property` in the
sub-editors schema-data. If pressent, it tells the multiple-editor which property to look for in the
data supplied via setValue. If this property is found and has the correct value, then this sub-editor is selected.

If we have this schema:

```json
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"child": {
"oneOf": [
{
"$ref": "#/definitions/Boy"
},
{
"$ref": "#/definitions/Girl"
}
]
}
},
"definitions": {
"Boy": {
"type": "object",
"title": "Boy",
"options": {
"multiple_editor_select_via_property": {
"property": "sex",
"value": "boy"
}
},
"properties": {
"sex": {
"type": "string",
"enum": [
"boy"
],
"default": "boy",
"options": {
"hidden": true
}
},
"name": {
"type": "string"
},
"age": {
"type": "number",
"minimum": 10
}
},
"required": ["sex"]
},
"Girl": {
"type": "object",
"title": "Girl",
"options": {
"multiple_editor_select_via_property": {
"property": "sex",
"value": "girl"
}
},
"properties": {
"sex": {
"type": "string",
"enum": [
"girl"
],
"default": "girl",
"options": {
"hidden": true
}
},
"name": {
"type": "string"
},
"age": {
"type": "number",
"minimum": 10
}
},
"required": ["sex"]
}
}
}
```

Then the following json..

```json
{
"child": {
"sex": "girl",
"name": "Gry",
"age": 5
}
}

```
.. would make the multiple-editor select the correct Girl-sub-editor
even though the age = 5 is failing the editors validation.

This feature is used when generating json-schema for Java- or Scala-classes which contains polymorphism using [mbknor-jackson-jsonSchema](https://github.com/mbknor/mbknor-jackson-jsonSchema).


Editor Options
----------------
Expand All @@ -771,6 +885,7 @@ Editors can accept options which alter the behavior in some way.
* `input_height` - Explicitly set the height of the input element. Should be a valid CSS width string (e.g. "100px"). Works best with textareas.
* `input_width` - Explicitly set the width of the input element. Should be a valid CSS width string (e.g. "100px"). Works for string, number, and integer data types.
* `remove_empty_properties` - If set to true for an object, empty object properties (i.e. those with falsy values) will not be returned by getValue().
* `multiple_editor_select_via_property` - This can be used to instruct the multiple-editor (eg: oneOf) to select the correct sub-editor.

```json
{
Expand Down
35 changes: 31 additions & 4 deletions src/editors/multiple.js
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -232,12 +232,39 @@ JSONEditor.defaults.editors.multiple = JSONEditor.AbstractEditor.extend({
},
setValue: function(val,initial) {
// Determine type by getting the first one that validates
// or by using multiple_editor_select_via_property
var self = this;
$each(this.validators, function(i,validator) {
if(!validator.validate(val).length) {
self.type = i;
self.switcher.value = self.display_text[i];
return false;

// If this editor's schema has the option:
// "options": {
// "multiple_editor_select_via_property": {
// "property": "myProperty",
// "value": "myValue"
// }
// }
// we'll select this editor if val.type = 'myValue'
if(self.types[i] && self.types[i].hasOwnProperty("options") && self.types[i].options.hasOwnProperty("multiple_editor_select_via_property")){
// This editor's schema has multiple_editor_select_via_property
var multiple_editor_select_via_property = self.types[i].options.multiple_editor_select_via_property;

var propName = multiple_editor_select_via_property.property;
var propValue = multiple_editor_select_via_property.value;

// Must check if val has this property with the correct value
if(typeof val !== "undefined" && val !== null && val.hasOwnProperty(propName) && val[propName] == propValue) {
// This is a match
self.type = i;
self.switcher.value = self.display_text[i];
return false;
}
} else {
// else, we select this editor, if it has no validation errors
if(!validator.validate(val).length) {
self.type = i;
self.switcher.value = self.display_text[i];
return false;
}
}
});

Expand Down