Skip to content

Commit 7460578

Browse files
committed
Add option for when to show validation errors. Changed default behavior to be on interaction. Fixes #194
1 parent f46ed33 commit 7460578

File tree

8 files changed

+133
-39
lines changed

8 files changed

+133
-39
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ Here are all the available options:
140140
<td>A valid JSON Schema to use for the editor. Version 3 and Version 4 of the draft specification are supported.</td>
141141
<td><code>{}</code></td>
142142
</tr>
143+
<tr>
144+
<td>show_errors</td>
145+
<td>When to show validation errors in the UI. Valid values are <code>interaction</code>, <code>change</code>, <code>always</code>, and <code>never</code>.</td>
146+
<td><code>"interaction"</code></td>
147+
</tr>
143148
<tr>
144149
<td>startval</td>
145150
<td>Seed the editor with an initial value. This should be valid against the editor's schema.</td>

bower.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "json-editor",
3-
"version": "0.6.19",
3+
"version": "0.7.1",
44
"authors": [
55
"Jeremy Dorn <[email protected]>"
66
],

demo.html

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,15 @@ <h2>Options</h2>
6565
<option value='grid'>grid</option>
6666
</select>
6767
</div>
68+
<div>
69+
<label>Show Errors</label>
70+
<select id='show_errors' class='form-control'>
71+
<option value='interaction'>On Interaction</option>
72+
<option value='change'>On Field Change</option>
73+
<option value='always'>Always</option>
74+
<option value='never'>Never</option>
75+
</select>
76+
</div>
6877
<div>
6978
<label>Boolean options</label>
7079
<select multiple size=9 id='boolean_options' style='width: 100%;' class='form-control'>
@@ -258,7 +267,8 @@ <h2>Code</h2>
258267
};
259268

260269
var reload = function(keep_value) {
261-
var startval = (jsoneditor && keep_value)? jsoneditor.getValue() : undefined;
270+
var startval = (jsoneditor && keep_value)? jsoneditor.getValue() : window.startval;
271+
window.startval = undefined;
262272

263273
if(jsoneditor) jsoneditor.destroy();
264274
jsoneditor = new JSONEditor($editor,{
@@ -372,25 +382,39 @@ <h2>Code</h2>
372382
JSONEditor.defaults.options.object_layout = this.value;
373383
reload(true);
374384
});
385+
document.getElementById('show_errors').addEventListener('change',function() {
386+
JSONEditor.defaults.options.show_errors = this.value;
387+
reload(true);
388+
});
375389
document.getElementById('boolean_options').addEventListener('change',function() {
376390
refreshBooleanOptions();
377391
});
378-
392+
393+
// Get starting value from url
394+
if(window.location.href.match('[?&]value=([^&]+)')) {
395+
window.startval = JSON.parse(LZString.decompressFromBase64(window.location.href.match('[?&]value=([^&]+)')[1]));
396+
}
397+
379398
// Set options from direct link
380399
setTheme((window.location.href.match(/[?&]theme=([^&]+)/)||[])[1] || 'bootstrap2', true);
400+
381401
setIconlib((window.location.href.match(/[?&]iconlib=([^&]*)/)||[null,'fontawesome4'])[1], true);
402+
382403
document.getElementById('object_layout').value = (window.location.href.match(/[?&]object_layout=([^&]+)/)||[])[1] || 'normal';
404+
JSONEditor.defaults.options.object_layout = document.getElementById('object_layout').value;
405+
406+
document.getElementById('show_errors').value = (window.location.href.match(/[?&]show_errors=([^&]+)/)||[])[1] || 'interaction';
407+
JSONEditor.defaults.options.show_errors = document.getElementById('show_errors').value;
408+
383409
var boolean_options = document.getElementById('boolean_options').children;
384410
for(var i=0; i<boolean_options.length; i++) {
385411
if(window.location.href.match(new RegExp('[?&]'+boolean_options[i].getAttribute('value')+'([&=]|$)'))) {
386412
boolean_options[i].selected = true;
387413
}
388414
}
389415
refreshBooleanOptions(true);
416+
390417
reload();
391-
if(window.location.href.match('[?&]value=([^&]+)')) {
392-
jsoneditor.setValue(JSON.parse(LZString.decompressFromBase64(window.location.href.match('[?&]value=([^&]+)')[1])));
393-
}
394418
})();
395419
</script>
396420
</body>

dist/jsoneditor.js

Lines changed: 72 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
/*! JSON Editor v0.7.0 - JSON Schema -> HTML Editor
1+
/*! JSON Editor v0.7.1 - JSON Schema -> HTML Editor
22
* By Jeremy Dorn - https://github.com/jdorn/json-editor/
33
* Released under the MIT license
44
*
5-
* Date: 2014-07-13
5+
* Date: 2014-07-24
66
*/
77

88
/**
@@ -370,7 +370,10 @@ JSONEditor.prototype = {
370370

371371
// Validate and cache results
372372
self.validation_results = self.validator.validate(self.root.getValue());
373-
self.root.showValidationErrors(self.validation_results);
373+
374+
if(self.options.show_errors !== "never") {
375+
self.root.showValidationErrors(self.validation_results);
376+
}
374377

375378
// Fire change event
376379
self.trigger('change');
@@ -1759,7 +1762,10 @@ JSONEditor.defaults.editors.string = JSONEditor.AbstractEditor.extend({
17591762
var changed = from_template || this.getValue() !== value;
17601763

17611764
this.refreshValue();
1762-
1765+
1766+
if(initial) this.is_dirty = false;
1767+
else if(this.jsoneditor.options.show_errors === "change") this.is_dirty = true;
1768+
17631769
if(changed) {
17641770
if(self.parent) self.parent.onChildEditorChange(self);
17651771
else self.jsoneditor.onChange();
@@ -1977,6 +1983,8 @@ JSONEditor.defaults.editors.string = JSONEditor.AbstractEditor.extend({
19771983
if(val !== sanitized) {
19781984
this.value = sanitized;
19791985
}
1986+
1987+
self.is_dirty = true;
19801988

19811989
self.refreshValue();
19821990
self.watch_listener();
@@ -2053,6 +2061,7 @@ JSONEditor.defaults.editors.string = JSONEditor.AbstractEditor.extend({
20532061
// Set the value and update
20542062
self.input.value = val.html();
20552063
self.value = self.input.value;
2064+
self.is_dirty = true;
20562065
if(self.parent) self.parent.onChildEditorChange(self);
20572066
else self.jsoneditor.onChange();
20582067
self.jsoneditor.notifyWatchers(self.path);
@@ -2077,6 +2086,7 @@ JSONEditor.defaults.editors.string = JSONEditor.AbstractEditor.extend({
20772086
var val = self.epiceditor.exportFile();
20782087
self.input.value = val;
20792088
self.value = val;
2089+
self.is_dirty = true;
20802090
if(self.parent) self.parent.onChildEditorChange(self);
20812091
else self.jsoneditor.onChange();
20822092
self.jsoneditor.notifyWatchers(self.path);
@@ -2111,6 +2121,7 @@ JSONEditor.defaults.editors.string = JSONEditor.AbstractEditor.extend({
21112121
var val = self.ace_editor.getValue();
21122122
self.input.value = val;
21132123
self.refreshValue();
2124+
self.is_dirty = true;
21142125
if(self.parent) self.parent.onChildEditorChange(self);
21152126
else self.jsoneditor.onChange();
21162127
self.jsoneditor.notifyWatchers(self.path);
@@ -2249,6 +2260,11 @@ JSONEditor.defaults.editors.string = JSONEditor.AbstractEditor.extend({
22492260
},
22502261
showValidationErrors: function(errors) {
22512262
var self = this;
2263+
2264+
if(this.jsoneditor.options.show_errors === "always") {}
2265+
else if(!this.is_dirty) return;
2266+
2267+
22522268

22532269
var messages = [];
22542270
$each(errors,function(i,error) {
@@ -2430,11 +2446,12 @@ JSONEditor.defaults.editors.object = JSONEditor.AbstractEditor.extend({
24302446
var row = this.theme.getGridRow();
24312447
container.appendChild(row);
24322448
for(j=0; j<rows[i].editors.length; j++) {
2433-
var editor = this.editors[rows[i].editors[j].key];
2449+
var key = rows[i].editors[j].key;
2450+
var editor = this.editors[key];
24342451

24352452
if(editor.options.hidden) editor.container.style.display = 'none';
24362453
else this.theme.setGridColumnSize(editor.container,rows[i].editors[j].width);
2437-
2454+
editor.container.className += ' container-' + key;
24382455
row.appendChild(editor.container);
24392456
}
24402457
}
@@ -2449,7 +2466,7 @@ JSONEditor.defaults.editors.object = JSONEditor.AbstractEditor.extend({
24492466

24502467
if(editor.options.hidden) editor.container.style.display = 'none';
24512468
else self.theme.setGridColumnSize(editor.container,12);
2452-
2469+
editor.container.className += ' container-' + key;
24532470
row.appendChild(editor.container);
24542471
});
24552472
}
@@ -2577,11 +2594,15 @@ JSONEditor.defaults.editors.object = JSONEditor.AbstractEditor.extend({
25772594
this.editjson_textarea.style.width = '300px';
25782595
this.editjson_textarea.style.display = 'block';
25792596
this.editjson_save = this.getButton('Save','save','Save');
2580-
this.editjson_save.addEventListener('click',function() {
2597+
this.editjson_save.addEventListener('click',function(e) {
2598+
e.preventDefault();
2599+
e.stopPropagation();
25812600
self.saveJSON();
25822601
});
25832602
this.editjson_cancel = this.getButton('Cancel','cancel','Cancel');
2584-
this.editjson_cancel.addEventListener('click',function() {
2603+
this.editjson_cancel.addEventListener('click',function(e) {
2604+
e.preventDefault();
2605+
e.stopPropagation();
25852606
self.hideEditJSON();
25862607
});
25872608
this.editjson_holder.appendChild(this.editjson_textarea);
@@ -2603,7 +2624,9 @@ JSONEditor.defaults.editors.object = JSONEditor.AbstractEditor.extend({
26032624
this.addproperty_input.style.width = '220px';
26042625
this.addproperty_input.style.marginBottom = '0';
26052626
this.addproperty_input.style.display = 'inline-block';
2606-
this.addproperty_add.addEventListener('click',function() {
2627+
this.addproperty_add.addEventListener('click',function(e) {
2628+
e.preventDefault();
2629+
e.stopPropagation();
26072630
if(self.addproperty_input.value) {
26082631
if(self.editors[self.addproperty_input.value]) {
26092632
alert('there is already a property with that name');
@@ -2664,7 +2687,9 @@ JSONEditor.defaults.editors.object = JSONEditor.AbstractEditor.extend({
26642687
this.collapsed = false;
26652688
this.toggle_button = this.getButton('','collapse','Collapse');
26662689
this.title_controls.appendChild(this.toggle_button);
2667-
this.toggle_button.addEventListener('click',function() {
2690+
this.toggle_button.addEventListener('click',function(e) {
2691+
e.preventDefault();
2692+
e.stopPropagation();
26682693
if(self.collapsed) {
26692694
self.editor_holder.style.display = '';
26702695
self.collapsed = false;
@@ -2692,7 +2717,9 @@ JSONEditor.defaults.editors.object = JSONEditor.AbstractEditor.extend({
26922717

26932718
// Edit JSON Button
26942719
this.editjson_button = this.getButton('JSON','edit','Edit JSON');
2695-
this.editjson_button.addEventListener('click',function() {
2720+
this.editjson_button.addEventListener('click',function(e) {
2721+
e.preventDefault();
2722+
e.stopPropagation();
26962723
self.toggleEditJSON();
26972724
});
26982725
this.editjson_controls.appendChild(this.editjson_button);
@@ -2708,7 +2735,9 @@ JSONEditor.defaults.editors.object = JSONEditor.AbstractEditor.extend({
27082735

27092736
// Object Properties Button
27102737
this.addproperty_button = this.getButton('Properties','edit','Object Properties');
2711-
this.addproperty_button.addEventListener('click',function() {
2738+
this.addproperty_button.addEventListener('click',function(e) {
2739+
e.preventDefault();
2740+
e.stopPropagation();
27122741
self.toggleAddProperty();
27132742
});
27142743
this.addproperty_controls.appendChild(this.addproperty_button);
@@ -3558,7 +3587,9 @@ JSONEditor.defaults.editors.array = JSONEditor.AbstractEditor.extend({
35583587
self.rows[i].delete_button = this.getButton(self.getItemTitle(),'delete','Delete '+self.getItemTitle());
35593588
self.rows[i].delete_button.className += ' delete';
35603589
self.rows[i].delete_button.setAttribute('data-i',i);
3561-
self.rows[i].delete_button.addEventListener('click',function() {
3590+
self.rows[i].delete_button.addEventListener('click',function(e) {
3591+
e.preventDefault();
3592+
e.stopPropagation();
35623593
var i = this.getAttribute('data-i')*1;
35633594

35643595
var value = self.getValue();
@@ -3598,7 +3629,9 @@ JSONEditor.defaults.editors.array = JSONEditor.AbstractEditor.extend({
35983629
self.rows[i].moveup_button = this.getButton('','moveup','Move up');
35993630
self.rows[i].moveup_button.className += ' moveup';
36003631
self.rows[i].moveup_button.setAttribute('data-i',i);
3601-
self.rows[i].moveup_button.addEventListener('click',function() {
3632+
self.rows[i].moveup_button.addEventListener('click',function(e) {
3633+
e.preventDefault();
3634+
e.stopPropagation();
36023635
var i = this.getAttribute('data-i')*1;
36033636

36043637
if(i<=0) return;
@@ -3624,7 +3657,9 @@ JSONEditor.defaults.editors.array = JSONEditor.AbstractEditor.extend({
36243657
self.rows[i].movedown_button = this.getButton('','movedown','Move down');
36253658
self.rows[i].movedown_button.className += ' movedown';
36263659
self.rows[i].movedown_button.setAttribute('data-i',i);
3627-
self.rows[i].movedown_button.addEventListener('click',function() {
3660+
self.rows[i].movedown_button.addEventListener('click',function(e) {
3661+
e.preventDefault();
3662+
e.stopPropagation();
36283663
var i = this.getAttribute('data-i')*1;
36293664

36303665
var rows = self.getValue();
@@ -3656,7 +3691,9 @@ JSONEditor.defaults.editors.array = JSONEditor.AbstractEditor.extend({
36563691
this.title_controls.appendChild(this.toggle_button);
36573692
var row_holder_display = self.row_holder.style.display;
36583693
var controls_display = self.controls.style.display;
3659-
this.toggle_button.addEventListener('click',function() {
3694+
this.toggle_button.addEventListener('click',function(e) {
3695+
e.preventDefault();
3696+
e.stopPropagation();
36603697
if(self.collapsed) {
36613698
self.collapsed = false;
36623699
if(self.panel) self.panel.style.display = '';
@@ -3691,7 +3728,9 @@ JSONEditor.defaults.editors.array = JSONEditor.AbstractEditor.extend({
36913728
// Add "new row" and "delete last" buttons below editor
36923729
this.add_row_button = this.getButton(this.getItemTitle(),'add','Add '+this.getItemTitle());
36933730

3694-
this.add_row_button.addEventListener('click',function() {
3731+
this.add_row_button.addEventListener('click',function(e) {
3732+
e.preventDefault();
3733+
e.stopPropagation();
36953734
var i = self.rows.length;
36963735
if(self.row_cache[i]) {
36973736
self.rows[i] = self.row_cache[i];
@@ -3712,7 +3751,9 @@ JSONEditor.defaults.editors.array = JSONEditor.AbstractEditor.extend({
37123751
self.controls.appendChild(this.add_row_button);
37133752

37143753
this.delete_last_row_button = this.getButton('Last '+this.getItemTitle(),'delete','Delete Last '+this.getItemTitle());
3715-
this.delete_last_row_button.addEventListener('click',function() {
3754+
this.delete_last_row_button.addEventListener('click',function(e) {
3755+
e.preventDefault();
3756+
e.stopPropagation();
37163757
var rows = self.getValue();
37173758

37183759
var new_active_tab = null;
@@ -3730,7 +3771,9 @@ JSONEditor.defaults.editors.array = JSONEditor.AbstractEditor.extend({
37303771
self.controls.appendChild(this.delete_last_row_button);
37313772

37323773
this.remove_all_rows_button = this.getButton('All','delete','Delete All');
3733-
this.remove_all_rows_button.addEventListener('click',function() {
3774+
this.remove_all_rows_button.addEventListener('click',function(e) {
3775+
e.preventDefault();
3776+
e.stopPropagation();
37343777
self.setValue([]);
37353778
if(self.parent) self.parent.onChildEditorChange(self);
37363779
else self.jsoneditor.onChange();
@@ -4121,7 +4164,9 @@ JSONEditor.defaults.editors.table = JSONEditor.defaults.editors.array.extend({
41214164
self.rows[i].delete_button = this.getButton('','delete','Delete');
41224165
self.rows[i].delete_button.className += ' delete';
41234166
self.rows[i].delete_button.setAttribute('data-i',i);
4124-
self.rows[i].delete_button.addEventListener('click',function() {
4167+
self.rows[i].delete_button.addEventListener('click',function(e) {
4168+
e.preventDefault();
4169+
e.stopPropagation();
41254170
var i = this.getAttribute('data-i')*1;
41264171

41274172
var value = self.getValue();
@@ -4144,7 +4189,9 @@ JSONEditor.defaults.editors.table = JSONEditor.defaults.editors.array.extend({
41444189
self.rows[i].moveup_button = this.getButton('','moveup','Move up');
41454190
self.rows[i].moveup_button.className += ' moveup';
41464191
self.rows[i].moveup_button.setAttribute('data-i',i);
4147-
self.rows[i].moveup_button.addEventListener('click',function() {
4192+
self.rows[i].moveup_button.addEventListener('click',function(e) {
4193+
e.preventDefault();
4194+
e.stopPropagation();
41484195
var i = this.getAttribute('data-i')*1;
41494196

41504197
if(i<=0) return;
@@ -4164,7 +4211,9 @@ JSONEditor.defaults.editors.table = JSONEditor.defaults.editors.array.extend({
41644211
self.rows[i].movedown_button = this.getButton('','movedown','Move down');
41654212
self.rows[i].movedown_button.className += ' movedown';
41664213
self.rows[i].movedown_button.setAttribute('data-i',i);
4167-
self.rows[i].movedown_button.addEventListener('click',function() {
4214+
self.rows[i].movedown_button.addEventListener('click',function(e) {
4215+
e.preventDefault();
4216+
e.stopPropagation();
41684217
var i = this.getAttribute('data-i')*1;
41694218
var rows = self.getValue();
41704219
if(i>=rows.length-1) return;

dist/jsoneditor.min.js

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/core.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,10 @@ JSONEditor.prototype = {
176176

177177
// Validate and cache results
178178
self.validation_results = self.validator.validate(self.root.getValue());
179-
self.root.showValidationErrors(self.validation_results);
179+
180+
if(self.options.show_errors !== "never") {
181+
self.root.showValidationErrors(self.validation_results);
182+
}
180183

181184
// Fire change event
182185
self.trigger('change');

0 commit comments

Comments
 (0)