@json-editor/json-editor 2.10.0 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@json-editor/json-editor",
3
3
  "title": "JSONEditor",
4
4
  "description": "JSON Schema based editor",
5
- "version": "2.10.0",
5
+ "version": "2.11.0",
6
6
  "main": "dist/jsoneditor.js",
7
7
  "author": {
8
8
  "name": "Jeremy Dorn",
@@ -1,7 +1,7 @@
1
1
  /* Multiple Editor (for when `type` is an array, also when `oneOf` is present) */
2
2
  import { AbstractEditor } from '../editor.js'
3
3
  import { Validator } from '../validator.js'
4
- import { extend, mergeDeep } from '../utilities.js'
4
+ import { extend, mergeDeep, overwriteExistingProperties } from '../utilities.js'
5
5
 
6
6
  export class MultipleEditor extends AbstractEditor {
7
7
  register () {
@@ -62,7 +62,7 @@ export class MultipleEditor extends AbstractEditor {
62
62
  this.buildChildEditor(i)
63
63
  }
64
64
 
65
- const currentValue = this.getValue()
65
+ let currentValue = this.getValue()
66
66
 
67
67
  this.type = i
68
68
 
@@ -72,6 +72,10 @@ export class MultipleEditor extends AbstractEditor {
72
72
  if (!editor) return
73
73
 
74
74
  if (this.type === type) {
75
+ if (this.keep_only_existing_values) {
76
+ currentValue = overwriteExistingProperties(editor.getValue(), currentValue)
77
+ }
78
+
75
79
  if (this.keep_values || this.if) editor.setValue(currentValue, true)
76
80
  editor.container.style.display = ''
77
81
  } else {
@@ -138,6 +142,10 @@ export class MultipleEditor extends AbstractEditor {
138
142
  if (typeof this.jsoneditor.options.keep_oneof_values !== 'undefined') this.keep_values = this.jsoneditor.options.keep_oneof_values
139
143
  if (typeof this.options.keep_oneof_values !== 'undefined') this.keep_values = this.options.keep_oneof_values
140
144
 
145
+ this.keep_only_existing_values = false
146
+ if (typeof this.jsoneditor.options.keep_only_existing_values !== 'undefined') this.keep_only_existing_values = this.jsoneditor.options.keep_only_existing_values
147
+ if (typeof this.options.keep_only_existing_values !== 'undefined') this.keep_only_existing_values = this.options.keep_only_existing_values
148
+
141
149
  if (this.schema.oneOf) {
142
150
  this.oneOf = true
143
151
  this.types = this.schema.oneOf
@@ -244,6 +252,10 @@ export class MultipleEditor extends AbstractEditor {
244
252
  this.validators[i] = new Validator(this.jsoneditor, schema, validatorOptions, this.defaults)
245
253
  })
246
254
 
255
+ this.jsoneditor.on('change', () => {
256
+ this.switchIf()
257
+ })
258
+
247
259
  this.switchEditor(0)
248
260
  }
249
261
 
@@ -253,7 +265,6 @@ export class MultipleEditor extends AbstractEditor {
253
265
  this.refreshHeaderText()
254
266
  }
255
267
 
256
- this.switchIf()
257
268
  super.onChildEditorChange()
258
269
  }
259
270
 
package/src/utilities.js CHANGED
@@ -126,3 +126,13 @@ export function mergeDeep (target, ...sources) {
126
126
 
127
127
  return mergeDeep(target, ...sources)
128
128
  }
129
+
130
+ export function overwriteExistingProperties (obj1, obj2) {
131
+ Object.keys(obj2).forEach(function (key) {
132
+ if (key in obj1) {
133
+ obj1[key] = obj2[key]
134
+ }
135
+ })
136
+
137
+ return obj1
138
+ }
@@ -68,23 +68,27 @@ Scenario('validate agaist if-then-else @if-then-else', async ({ I }) => {
68
68
  I.waitForElement('.je-ready')
69
69
 
70
70
  I.selectOption('[name="root[country]"]', 'America')
71
+ I.waitForElement('[name="root[postal_code]"]')
71
72
  I.fillField('[name="root[postal_code]"]', 'K1M 1M4')
72
73
  I.pressKey('Tab')
73
74
  I.waitForElement('.invalid-feedback')
74
75
  I.waitForText('Value must match the pattern [0-9]{5}(-[0-9]{4})?.')
75
76
 
76
77
  I.selectOption('[name="root[country]"]', 'Canada')
78
+ I.waitForElement('[name="root[postal_code]"]')
77
79
  I.fillField('[name="root[postal_code]"]', '10000')
78
80
  I.pressKey('Tab')
79
81
  I.waitForElement('.invalid-feedback')
80
82
  I.waitForText('Value must match the pattern [A-Z][0-9][A-Z] [0-9][A-Z][0-9].')
81
83
 
82
84
  I.selectOption('[name="root[country]"]', 'America')
85
+ I.waitForElement('[name="root[postal_code]"]')
83
86
  I.fillField('[name="root[postal_code]"]', '10000')
84
87
  I.pressKey('Tab')
85
88
  I.dontSee('.invalid-feedback')
86
89
 
87
90
  I.selectOption('[name="root[country]"]', 'Canada')
91
+ I.waitForElement('[name="root[postal_code]"]')
88
92
  I.fillField('[name="root[postal_code]"]', 'K1M 1M4')
89
93
  I.pressKey('Tab')
90
94
  I.dontSee('.invalid-feedback')
@@ -95,22 +99,26 @@ Scenario('validate agaist if-then @if-then-else', async ({ I }) => {
95
99
  I.waitForElement('.je-ready')
96
100
 
97
101
  I.selectOption('[name="root[country]"]', 'America')
102
+ I.waitForElement('[name="root[postal_code]"]')
98
103
  I.fillField('[name="root[postal_code]"]', 'K1M 1M4')
99
104
  I.pressKey('Tab')
100
105
  I.waitForElement('.invalid-feedback')
101
106
  I.waitForText('Value must match the pattern [0-9]{5}(-[0-9]{4})?.')
102
107
 
103
108
  I.selectOption('[name="root[country]"]', 'Canada')
109
+ I.waitForElement('[name="root[postal_code]"]')
104
110
  I.fillField('[name="root[postal_code]"]', '10000')
105
111
  I.pressKey('Tab')
106
112
  I.dontSee('.invalid-feedback')
107
113
 
108
114
  I.selectOption('[name="root[country]"]', 'America')
115
+ I.waitForElement('[name="root[postal_code]"]')
109
116
  I.fillField('[name="root[postal_code]"]', '10000')
110
117
  I.pressKey('Tab')
111
118
  I.dontSee('.invalid-feedback')
112
119
 
113
120
  I.selectOption('[name="root[country]"]', 'Canada')
121
+ I.waitForElement('[name="root[postal_code]"]')
114
122
  I.fillField('[name="root[postal_code]"]', 'K1M 1M4')
115
123
  I.pressKey('Tab')
116
124
  I.dontSee('.invalid-feedback')
@@ -121,22 +129,57 @@ Scenario('validate agaist if-else @if-then-else', async ({ I }) => {
121
129
  I.waitForElement('.je-ready')
122
130
 
123
131
  I.selectOption('[name="root[country]"]', 'America')
132
+ I.waitForElement('[name="root[postal_code]"]')
124
133
  I.fillField('[name="root[postal_code]"]', 'K1M 1M4')
125
134
  I.pressKey('Tab')
126
135
  I.dontSee('.invalid-feedback')
127
136
 
128
137
  I.selectOption('[name="root[country]"]', 'Canada')
138
+ I.waitForElement('[name="root[postal_code]"]')
129
139
  I.fillField('[name="root[postal_code]"]', '10000')
130
140
  I.pressKey('Tab')
131
141
  I.waitForElement('.invalid-feedback')
132
142
  I.waitForText('Value must match the pattern [A-Z][0-9][A-Z] [0-9][A-Z][0-9].')
133
143
 
134
144
  I.selectOption('[name="root[country]"]', 'America')
145
+ I.waitForElement('[name="root[postal_code]"]')
135
146
  I.fillField('[name="root[postal_code]"]', '10000')
136
147
  I.pressKey('Tab')
137
148
  I.dontSee('.invalid-feedback')
138
149
 
139
150
  I.selectOption('[name="root[country]"]', 'Canada')
151
+ I.waitForElement('[name="root[postal_code]"]')
152
+ I.fillField('[name="root[postal_code]"]', 'K1M 1M4')
153
+ I.pressKey('Tab')
154
+ I.dontSee('.invalid-feedback')
155
+ })
156
+
157
+ Scenario('validate agaist if-then-else when disabled fields are present in fields @if-then-else', async ({ I }) => {
158
+ I.amOnPage('if-then-else-disable-fields.html')
159
+ I.waitForElement('.je-ready')
160
+
161
+ I.selectOption('[name="root[country]"]', 'America')
162
+ I.waitForElement('[name="root[postal_code]"]')
163
+ I.fillField('[name="root[postal_code]"]', 'K1M 1M4')
164
+ I.pressKey('Tab')
165
+ I.waitForElement('.invalid-feedback')
166
+ I.waitForText('Value must match the pattern [0-9]{5}(-[0-9]{4})?.')
167
+
168
+ I.selectOption('[name="root[country]"]', 'Canada')
169
+ I.waitForElement('[name="root[postal_code]"]')
170
+ I.fillField('[name="root[postal_code]"]', '10000')
171
+ I.pressKey('Tab')
172
+ I.waitForElement('.invalid-feedback')
173
+ I.waitForText('Value must match the pattern [A-Z][0-9][A-Z] [0-9][A-Z][0-9].')
174
+
175
+ I.selectOption('[name="root[country]"]', 'America')
176
+ I.waitForElement('[name="root[postal_code]"]')
177
+ I.fillField('[name="root[postal_code]"]', '10000')
178
+ I.pressKey('Tab')
179
+ I.dontSee('.invalid-feedback')
180
+
181
+ I.selectOption('[name="root[country]"]', 'Canada')
182
+ I.waitForElement('[name="root[postal_code]"]')
140
183
  I.fillField('[name="root[postal_code]"]', 'K1M 1M4')
141
184
  I.pressKey('Tab')
142
185
  I.dontSee('.invalid-feedback')
@@ -170,6 +170,14 @@ Scenario('should validate against anyOf schemas and display single anyOf and edi
170
170
  I.dontSee('Property must be set.', '[data-schemapath="root.age"] .invalid-feedback')
171
171
  })
172
172
 
173
+ Scenario('should keep only existent values @core @anyof @keep_only_existing_values', async ({ I }) => {
174
+ I.amOnPage('keep_only_existing_values.html')
175
+ I.waitForElement('.je-ready')
176
+ I.waitForValue('#value', '{"name":"Afred","surname":"hitchcock","zip":"12345"}')
177
+ I.selectOption('.je-switcher', 'object 2')
178
+ I.waitForValue('#value', '{"name":"Afred","surname":"hitchcock","other_zip":""}')
179
+ })
180
+
173
181
  Scenario('should display anyOf and oneOf error messages in the correct places @848', async ({ I }) => {
174
182
  I.amOnPage('issues/issue-gh-848.html')
175
183
  I.selectOption('.je-switcher', 'Value, string')
@@ -0,0 +1,69 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8"/>
5
+ <title>If-Then-Else</title>
6
+ <script src="../../dist/jsoneditor.js"></script>
7
+ <link rel="stylesheet" id="theme-link" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
8
+ <link rel="stylesheet" id="iconlib-link" href="https://use.fontawesome.com/releases/v5.6.1/css/all.css">
9
+ </head>
10
+ <body>
11
+
12
+ <div class="container">
13
+ <div id='editor-container'></div>
14
+ </div>
15
+
16
+ <script>
17
+ var editorContainer = document.querySelector('#editor-container')
18
+ var schema = {
19
+ 'type': 'object',
20
+ 'properties': {
21
+ "id": {
22
+ "type": "string",
23
+ "format": "uuid",
24
+ "title": "ID"
25
+ },
26
+ 'country': {
27
+ 'type': 'string',
28
+ 'default': 'America',
29
+ 'enum': [
30
+ 'America',
31
+ 'Canada'
32
+ ]
33
+ },
34
+ 'postal_code': {
35
+ 'type': 'string'
36
+ }
37
+ },
38
+ 'if': {
39
+ 'properties': {
40
+ 'country': {
41
+ 'const': 'America'
42
+ }
43
+ }
44
+ },
45
+ 'then': {
46
+ 'properties': {
47
+ 'postal_code': {
48
+ 'pattern': '[0-9]{5}(-[0-9]{4})?'
49
+ }
50
+ }
51
+ },
52
+ 'else': {
53
+ 'properties': {
54
+ 'postal_code': {
55
+ 'pattern': '[A-Z][0-9][A-Z] [0-9][A-Z][0-9]'
56
+ }
57
+ }
58
+ }
59
+ }
60
+
61
+ var editor = new JSONEditor(editorContainer, {
62
+ schema: schema,
63
+ theme: 'bootstrap4',
64
+ iconlib: 'fontawesome'
65
+ })
66
+ </script>
67
+
68
+ </body>
69
+ </html>
@@ -0,0 +1,80 @@
1
+ <!DOCTYPE html>
2
+ <html lang="de">
3
+ <head>
4
+ <meta charset="utf-8"/>
5
+ <title>oneOf</title>
6
+ <link rel="stylesheet" id="theme-link" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
7
+ <link rel="stylesheet" id="iconlib-link" href="https://use.fontawesome.com/releases/v5.6.1/css/all.css">
8
+ <script src="../../dist/jsoneditor.js"></script>
9
+ </head>
10
+ <body>
11
+
12
+ <div class="container">
13
+ <label for="value">Value</label>
14
+ <textarea class="form-control" id="value" rows="12" style="font-size: 12px; font-family: monospace;"></textarea>
15
+ <button id="set-value">Set Value</button>
16
+ <div class='json-editor-container'></div>
17
+ </div>
18
+
19
+ <script>
20
+ var jsonEditorContainer = document.querySelector('.json-editor-container')
21
+ var value = document.querySelector('#value')
22
+ var setValue = document.querySelector('#set-value')
23
+ var schema = {
24
+ 'anyOf': [
25
+ {
26
+ 'type': 'object',
27
+ 'properties': {
28
+ 'name': {
29
+ 'type': 'string',
30
+ "default": "Afred"
31
+ },
32
+ 'surname': {
33
+ 'type': 'string',
34
+ "default": "hitchcock"
35
+ },
36
+ 'zip': {
37
+ 'type': 'string',
38
+ "default": "12345"
39
+ }
40
+ }
41
+ },
42
+ {
43
+ 'type': 'object',
44
+ 'properties': {
45
+ 'name': {
46
+ 'type': 'string'
47
+ },
48
+ 'surname': {
49
+ 'type': 'string'
50
+ },
51
+ 'other_zip': {
52
+ 'type': 'string'
53
+ }
54
+ }
55
+ }
56
+ ]
57
+ }
58
+
59
+ var editor = new JSONEditor(jsonEditorContainer, {
60
+ schema: schema,
61
+ theme: 'bootstrap4',
62
+ show_errors: 'always',
63
+ iconlib: 'fontawesome5',
64
+ disable_collapse: true,
65
+ disable_edit_json: true,
66
+ disable_properties: true,
67
+ keep_only_existing_values: true
68
+ })
69
+
70
+ editor.on('change', function () {
71
+ value.value = JSON.stringify(editor.getValue())
72
+ })
73
+
74
+ setValue.addEventListener('click', function () {
75
+ editor.setValue(JSON.parse(value.value))
76
+ })
77
+ </script>
78
+
79
+ </body>
80
+ </html>