Skip to content

Commit 20805b6

Browse files
committed
Add disable_properties option, checkbox version of multiselect editor. Fixes #111 #105 #91
1 parent 29643da commit 20805b6

File tree

10 files changed

+171
-53
lines changed

10 files changed

+171
-53
lines changed

README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ Here are all the available options:
9090
<td>If <code>true</code>, remove all Edit JSON buttons from objects.</td>
9191
<td><code>false</code></td>
9292
</tr>
93+
<tr>
94+
<td>disable_properties</td>
95+
<td>If <code>true</code>, remove all Edit Properties buttons from objects.</td>
96+
<td><code>false</code></td>
97+
</tr>
9398
<tr>
9499
<td>form_name_root</td>
95100
<td>The first part of the `name` attribute of form inputs in the editor. An full example name is `root[person][name]` where "root" is the form_name_root.</td>
@@ -569,6 +574,35 @@ Here's an example of the `table` format:
569574
}
570575
```
571576

577+
For arrays of enumerated strings, you can also use the `select` or `checkbox` format. These formats require a very specific schema to work:
578+
579+
```json
580+
{
581+
"type": "array",
582+
"uniqueItems": true,
583+
"items": {
584+
"type": "string",
585+
"enum": ["value1","value2"]
586+
}
587+
}
588+
```
589+
590+
By default, the `checkbox` editor (multiple checkboxes) will be used if there are fewer than 8 enum options. Otherwise, the `select` editor (a multiselect box) will be used.
591+
592+
You can override this default by passing in a format:
593+
594+
```json
595+
{
596+
"type": "array",
597+
"format": "select",
598+
"uniqueItems": true,
599+
"items": {
600+
"type": "string",
601+
"enum": ["value1","value2"]
602+
}
603+
}
604+
```
605+
572606
#### Objects
573607

574608
The default object layout is one child editor per row. The `grid` format will instead put multiple child editors per row.
@@ -593,6 +627,7 @@ Editors can accept options which alter the behavior in some way.
593627
* `collapsed` - If set to true, the editor will start collapsed (works for objects and arrays)
594628
* `disable_collapse` - If set to true, the collapse button will be hidden (works for objects and arrays)
595629
* `disable_edit_json` - If set to true, the Edit JSON button will be hidden (works for objects)
630+
* `disable_properties` - If set to true, the Edit Properties button will be hidden (works for objects)
596631
* `hidden` - If set to true, the editor will not appear in the UI (works for all types)
597632

598633
```json

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.10",
3+
"version": "0.6.11",
44
"authors": [
55
"Jeremy Dorn <[email protected]>"
66
],

demo.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,13 @@ <h2>Options</h2>
6666
</div>
6767
<div>
6868
<label>Boolean options</label>
69-
<select multiple size=5 id='boolean_options' style='width: 100%;' class='form-control'>
69+
<select multiple size=6 id='boolean_options' style='width: 100%;' class='form-control'>
7070
<option value='required_by_default'>Object properties required by default</option>
7171
<option value='no_additional_properties'>No additional object properties</option>
7272
<option value='ajax'>Allow loading schemas via Ajax</option>
7373
<option value='disable_edit_json'>Disable "Edit JSON" buttons</option>
7474
<option value='disable_collapse'>Disable collapse buttons</option>
75+
<option value='disable_properties'>Disable properties buttons</option>
7576
</select>
7677
</div>
7778
</div>

dist/jsoneditor.js

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

88
/**
@@ -2968,7 +2968,12 @@ JSONEditor.defaults.editors.object = JSONEditor.AbstractEditor.extend({
29682968

29692969
if(this.adding_property) this.refreshAddProperties();
29702970
},
2971-
refreshAddProperties: function() {
2971+
refreshAddProperties: function() {
2972+
if(this.options.disable_properties || this.jsoneditor.options.disable_properties) {
2973+
this.addproperty_controls.style.display = 'none';
2974+
return;
2975+
}
2976+
29722977
var can_add = false, can_remove = false, num_props = 0, i, show_modal = false;
29732978

29742979
// Get number of editors
@@ -4852,7 +4857,6 @@ JSONEditor.defaults.editors.multiselect = JSONEditor.AbstractEditor.extend({
48524857
if(!this.getOption('compact',false)) this.header = this.label = this.theme.getFormInputLabel(this.getTitle());
48534858
if(this.schema.description) this.description = this.theme.getFormInputDescription(this.schema.description);
48544859

4855-
this.input_type = 'select';
48564860
this.select_options = {};
48574861
this.select_values = {};
48584862

@@ -4865,30 +4869,47 @@ JSONEditor.defaults.editors.multiselect = JSONEditor.AbstractEditor.extend({
48654869
options.push(e[i]+"");
48664870
this.select_values[e[i]+""] = e[i];
48674871
}
4868-
this.input = this.theme.getSelectInput(options);
4869-
this.input.multiple = true;
4870-
this.input.size = Math.min(10,options.length);
48714872

4872-
for(var i=0; i<options.length; i++) {
4873-
this.select_options[options[i]] = this.input.children[i];
4874-
}
4873+
if((!this.schema.format && options.length < 8) || this.schema.format === "checkbox") {
4874+
this.input_type = 'checkboxes';
48754875

4876-
if(this.schema.readOnly || this.schema.readonly) {
4877-
this.always_disabled = true;
4878-
this.input.disabled = true;
4876+
this.inputs = {};
4877+
this.controls = {};
4878+
for(var i=0; i<options.length; i++) {
4879+
this.inputs[options[i]] = this.theme.getCheckbox();
4880+
this.select_options[options[i]] = this.inputs[options[i]];
4881+
var label = this.theme.getCheckboxLabel(options[i]);
4882+
this.controls[options[i]] = this.theme.getFormControl(label, this.inputs[options[i]]);
4883+
}
4884+
4885+
this.control = this.theme.getMultiCheckboxHolder(this.controls,this.label,this.description);
48794886
}
4887+
else {
4888+
this.input_type = 'select';
4889+
this.input = this.theme.getSelectInput(options);
4890+
this.input.multiple = true;
4891+
this.input.size = Math.min(10,options.length);
48804892

4881-
this.control = this.getTheme().getFormControl(this.label, this.input, this.description);
4882-
this.container.appendChild(this.control);
4893+
for(var i=0; i<options.length; i++) {
4894+
this.select_options[options[i]] = this.input.children[i];
4895+
}
48834896

4897+
if(this.schema.readOnly || this.schema.readonly) {
4898+
this.always_disabled = true;
4899+
this.input.disabled = true;
4900+
}
48844901

4885-
this.input.addEventListener('change',function(e) {
4902+
this.control = this.getTheme().getFormControl(this.label, this.input, this.description);
4903+
}
4904+
4905+
this.container.appendChild(this.control);
4906+
this.control.addEventListener('change',function(e) {
48864907
e.preventDefault();
48874908
e.stopPropagation();
48884909

48894910
var new_value = [];
48904911
for(var i = 0; i<options.length; i++) {
4891-
if(self.select_options[options[i]].selected) new_value.push(self.select_values[options[i]]);
4912+
if(self.select_options[options[i]].selected || self.select_options[options[i]].checked) new_value.push(self.select_values[options[i]]);
48924913
}
48934914

48944915
self.updateValue(new_value);
@@ -4911,7 +4932,8 @@ JSONEditor.defaults.editors.multiselect = JSONEditor.AbstractEditor.extend({
49114932
// Update selected status of options
49124933
for(var i in this.select_options) {
49134934
if(!this.select_options.hasOwnProperty(i)) continue;
4914-
this.select_options[i].selected = (value.indexOf(i) !== -1);
4935+
4936+
this.select_options[i][this.input_type === "select"? "selected" : "checked"] = (value.indexOf(i) !== -1);
49154937
}
49164938

49174939
if(this.updateValue(value)) {
@@ -5036,7 +5058,9 @@ JSONEditor.AbstractTheme = Class.extend({
50365058
return el;
50375059
},
50385060
getCheckboxLabel: function(text) {
5039-
return this.getFormInputLabel(text);
5061+
var el = this.getFormInputLabel(text);
5062+
el.style.fontWeight = 'normal';
5063+
return el;
50405064
},
50415065
getHeader: function(text) {
50425066
var el = document.createElement('h3');
@@ -5051,7 +5075,26 @@ JSONEditor.AbstractTheme = Class.extend({
50515075
},
50525076
getCheckbox: function() {
50535077
var el = this.getFormInputField('checkbox');
5054-
el.style.marginRight = '5px';
5078+
el.style.display = 'inline-block';
5079+
el.style.width = 'auto';
5080+
return el;
5081+
},
5082+
getMultiCheckboxHolder: function(controls,label,description) {
5083+
var el = document.createElement('div');
5084+
5085+
label.style.display = 'block';
5086+
5087+
el.appendChild(label);
5088+
5089+
for(var i in controls) {
5090+
if(!controls.hasOwnProperty(i)) continue;
5091+
controls[i].style.display = 'inline-block';
5092+
controls[i].style.marginRight = '20px';
5093+
el.appendChild(controls[i]);
5094+
}
5095+
5096+
if(description) el.appendChild(description);
5097+
50555098
return el;
50565099
},
50575100
getSelectInput: function(options) {
@@ -5483,9 +5526,6 @@ JSONEditor.defaults.themes.bootstrap3 = JSONEditor.AbstractTheme.extend({
54835526
if(type !== 'checkbox') {
54845527
el.className += 'form-control';
54855528
}
5486-
else {
5487-
el.style.marginTop = '10px';
5488-
}
54895529
return el;
54905530
},
54915531
getFormControl: function(label, input, description) {
@@ -5495,6 +5535,7 @@ JSONEditor.defaults.themes.bootstrap3 = JSONEditor.AbstractTheme.extend({
54955535
group.className += ' checkbox';
54965536
label.appendChild(input);
54975537
label.style.fontSize = '14px';
5538+
group.style.marginTop = '0';
54985539
group.appendChild(label);
54995540
}
55005541
else {

dist/jsoneditor.min.js

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

src/editors/multiselect.js

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ JSONEditor.defaults.editors.multiselect = JSONEditor.AbstractEditor.extend({
77
if(!this.getOption('compact',false)) this.header = this.label = this.theme.getFormInputLabel(this.getTitle());
88
if(this.schema.description) this.description = this.theme.getFormInputDescription(this.schema.description);
99

10-
this.input_type = 'select';
1110
this.select_options = {};
1211
this.select_values = {};
1312

@@ -20,30 +19,47 @@ JSONEditor.defaults.editors.multiselect = JSONEditor.AbstractEditor.extend({
2019
options.push(e[i]+"");
2120
this.select_values[e[i]+""] = e[i];
2221
}
23-
this.input = this.theme.getSelectInput(options);
24-
this.input.multiple = true;
25-
this.input.size = Math.min(10,options.length);
2622

27-
for(var i=0; i<options.length; i++) {
28-
this.select_options[options[i]] = this.input.children[i];
29-
}
23+
if((!this.schema.format && options.length < 8) || this.schema.format === "checkbox") {
24+
this.input_type = 'checkboxes';
25+
26+
this.inputs = {};
27+
this.controls = {};
28+
for(var i=0; i<options.length; i++) {
29+
this.inputs[options[i]] = this.theme.getCheckbox();
30+
this.select_options[options[i]] = this.inputs[options[i]];
31+
var label = this.theme.getCheckboxLabel(options[i]);
32+
this.controls[options[i]] = this.theme.getFormControl(label, this.inputs[options[i]]);
33+
}
3034

31-
if(this.schema.readOnly || this.schema.readonly) {
32-
this.always_disabled = true;
33-
this.input.disabled = true;
35+
this.control = this.theme.getMultiCheckboxHolder(this.controls,this.label,this.description);
3436
}
37+
else {
38+
this.input_type = 'select';
39+
this.input = this.theme.getSelectInput(options);
40+
this.input.multiple = true;
41+
this.input.size = Math.min(10,options.length);
3542

36-
this.control = this.getTheme().getFormControl(this.label, this.input, this.description);
37-
this.container.appendChild(this.control);
43+
for(var i=0; i<options.length; i++) {
44+
this.select_options[options[i]] = this.input.children[i];
45+
}
3846

47+
if(this.schema.readOnly || this.schema.readonly) {
48+
this.always_disabled = true;
49+
this.input.disabled = true;
50+
}
51+
52+
this.control = this.getTheme().getFormControl(this.label, this.input, this.description);
53+
}
3954

40-
this.input.addEventListener('change',function(e) {
55+
this.container.appendChild(this.control);
56+
this.control.addEventListener('change',function(e) {
4157
e.preventDefault();
4258
e.stopPropagation();
4359

4460
var new_value = [];
4561
for(var i = 0; i<options.length; i++) {
46-
if(self.select_options[options[i]].selected) new_value.push(self.select_values[options[i]]);
62+
if(self.select_options[options[i]].selected || self.select_options[options[i]].checked) new_value.push(self.select_values[options[i]]);
4763
}
4864

4965
self.updateValue(new_value);
@@ -66,7 +82,8 @@ JSONEditor.defaults.editors.multiselect = JSONEditor.AbstractEditor.extend({
6682
// Update selected status of options
6783
for(var i in this.select_options) {
6884
if(!this.select_options.hasOwnProperty(i)) continue;
69-
this.select_options[i].selected = (value.indexOf(i) !== -1);
85+
86+
this.select_options[i][this.input_type === "select"? "selected" : "checked"] = (value.indexOf(i) !== -1);
7087
}
7188

7289
if(this.updateValue(value)) {

src/editors/object.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,12 @@ JSONEditor.defaults.editors.object = JSONEditor.AbstractEditor.extend({
607607

608608
if(this.adding_property) this.refreshAddProperties();
609609
},
610-
refreshAddProperties: function() {
610+
refreshAddProperties: function() {
611+
if(this.options.disable_properties || this.jsoneditor.options.disable_properties) {
612+
this.addproperty_controls.style.display = 'none';
613+
return;
614+
}
615+
611616
var can_add = false, can_remove = false, num_props = 0, i, show_modal = false;
612617

613618
// Get number of editors

src/intro.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
/*! JSON Editor v0.6.10 - JSON Schema -> HTML Editor
1+
/*! JSON Editor v0.6.11 - JSON Schema -> HTML Editor
22
* By Jeremy Dorn - https://github.com/jdorn/json-editor/
33
* Released under the MIT license
44
*
5-
* Date: 2014-05-27
5+
* Date: 2014-05-29
66
*/
77

88
/**

src/theme.js

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ JSONEditor.AbstractTheme = Class.extend({
5959
return el;
6060
},
6161
getCheckboxLabel: function(text) {
62-
return this.getFormInputLabel(text);
62+
var el = this.getFormInputLabel(text);
63+
el.style.fontWeight = 'normal';
64+
return el;
6365
},
6466
getHeader: function(text) {
6567
var el = document.createElement('h3');
@@ -74,7 +76,26 @@ JSONEditor.AbstractTheme = Class.extend({
7476
},
7577
getCheckbox: function() {
7678
var el = this.getFormInputField('checkbox');
77-
el.style.marginRight = '5px';
79+
el.style.display = 'inline-block';
80+
el.style.width = 'auto';
81+
return el;
82+
},
83+
getMultiCheckboxHolder: function(controls,label,description) {
84+
var el = document.createElement('div');
85+
86+
label.style.display = 'block';
87+
88+
el.appendChild(label);
89+
90+
for(var i in controls) {
91+
if(!controls.hasOwnProperty(i)) continue;
92+
controls[i].style.display = 'inline-block';
93+
controls[i].style.marginRight = '20px';
94+
el.appendChild(controls[i]);
95+
}
96+
97+
if(description) el.appendChild(description);
98+
7899
return el;
79100
},
80101
getSelectInput: function(options) {

0 commit comments

Comments
 (0)