Skip to content

Commit 82dc341

Browse files
committed
Fixing jdorn#709 by introducing multiple_editor_select_via_property
1 parent 26e2215 commit 82dc341

File tree

2 files changed

+146
-4
lines changed

2 files changed

+146
-4
lines changed

README.md

+115
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,120 @@ This can make the editor much more compact, but at a cost of not guaranteeing ch
749749
}
750750
```
751751

752+
#### Mulitple-editor (oneOf, anyOf, allOf)
753+
754+
When the schema uses oneOf (anyOf and allOf) the multiple-editor is used to hold the various sub-editors.
755+
It will also try to select the correct sub-editor when using setValue to initialize the editor with data.
756+
757+
The default behaviour is to select the first sub-editor that has no validation-errors testing using the supplied data.
758+
759+
Sometimes this sub-editor-selection needs to be more specific:
760+
761+
When checking if a particular sub-editor is the one that should be selected,
762+
the multiple-editor looks for an option called `multiple_editor_select_via_property` in the
763+
sub-editors schema-data. If pressent, it tells the multiple-editor which property to look for in the
764+
data supplied via setValue. If this property is found and has the correct value, then this sub-editor is selected.
765+
766+
If we have this schema:
767+
768+
```json
769+
{
770+
"$schema": "http://json-schema.org/draft-04/schema#",
771+
"type": "object",
772+
"properties": {
773+
"child": {
774+
"oneOf": [
775+
{
776+
"$ref": "#/definitions/Boy"
777+
},
778+
{
779+
"$ref": "#/definitions/Girl"
780+
}
781+
]
782+
}
783+
},
784+
"definitions": {
785+
"Boy": {
786+
"type": "object",
787+
"title": "Boy",
788+
"options": {
789+
"multiple_editor_select_via_property": {
790+
"property": "sex",
791+
"value": "boy"
792+
}
793+
},
794+
"properties": {
795+
"sex": {
796+
"type": "string",
797+
"enum": [
798+
"boy"
799+
],
800+
"default": "boy",
801+
"options": {
802+
"hidden": true
803+
}
804+
},
805+
"name": {
806+
"type": "string"
807+
},
808+
"age": {
809+
"type": "number",
810+
"minimum": 10
811+
}
812+
},
813+
"required": ["sex"]
814+
},
815+
"Girl": {
816+
"type": "object",
817+
"title": "Girl",
818+
"options": {
819+
"multiple_editor_select_via_property": {
820+
"property": "sex",
821+
"value": "girl"
822+
}
823+
},
824+
"properties": {
825+
"sex": {
826+
"type": "string",
827+
"enum": [
828+
"girl"
829+
],
830+
"default": "girl",
831+
"options": {
832+
"hidden": true
833+
}
834+
},
835+
"name": {
836+
"type": "string"
837+
},
838+
"age": {
839+
"type": "number",
840+
"minimum": 10
841+
}
842+
},
843+
"required": ["sex"]
844+
}
845+
}
846+
}
847+
```
848+
849+
Then the following json..
850+
851+
```json
852+
{
853+
"child": {
854+
"sex": "girl",
855+
"name": "Gry",
856+
"age": 5
857+
}
858+
}
859+
860+
```
861+
.. would make the multiple-editor select the correct Girl-sub-editor
862+
even though the age = 5 is failing the editors validation.
863+
864+
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).
865+
752866

753867
Editor Options
754868
----------------
@@ -771,6 +885,7 @@ Editors can accept options which alter the behavior in some way.
771885
* `input_height` - Explicitly set the height of the input element. Should be a valid CSS width string (e.g. "100px"). Works best with textareas.
772886
* `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.
773887
* `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().
888+
* `multiple_editor_select_via_property` - This can be used to instruct the multiple-editor (eg: oneOf) to select the correct sub-editor.
774889

775890
```json
776891
{

src/editors/multiple.js

100644100755
+31-4
Original file line numberDiff line numberDiff line change
@@ -232,12 +232,39 @@ JSONEditor.defaults.editors.multiple = JSONEditor.AbstractEditor.extend({
232232
},
233233
setValue: function(val,initial) {
234234
// Determine type by getting the first one that validates
235+
// or by using multiple_editor_select_via_property
235236
var self = this;
236237
$each(this.validators, function(i,validator) {
237-
if(!validator.validate(val).length) {
238-
self.type = i;
239-
self.switcher.value = self.display_text[i];
240-
return false;
238+
239+
// If this editor's schema has the option:
240+
// "options": {
241+
// "multiple_editor_select_via_property": {
242+
// "property": "myProperty",
243+
// "value": "myValue"
244+
// }
245+
// }
246+
// we'll select this editor if val.type = 'myValue'
247+
if(self.types[i] && self.types[i].hasOwnProperty("options") && self.types[i].options.hasOwnProperty("multiple_editor_select_via_property")){
248+
// This editor's schema has multiple_editor_select_via_property
249+
var multiple_editor_select_via_property = self.types[i].options.multiple_editor_select_via_property;
250+
251+
var propName = multiple_editor_select_via_property.property;
252+
var propValue = multiple_editor_select_via_property.value;
253+
254+
// Must check if val has this property with the correct value
255+
if(typeof val !== "undefined" && val !== null && val.hasOwnProperty(propName) && val[propName] == propValue) {
256+
// This is a match
257+
self.type = i;
258+
self.switcher.value = self.display_text[i];
259+
return false;
260+
}
261+
} else {
262+
// else, we select this editor, if it has no validation errors
263+
if(!validator.validate(val).length) {
264+
self.type = i;
265+
self.switcher.value = self.display_text[i];
266+
return false;
267+
}
241268
}
242269
});
243270

0 commit comments

Comments
 (0)