Skip to content
Closed
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
3 changes: 2 additions & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ module.exports = function(grunt) {
'src/editors/select.js',
'src/editors/multiselect.js',
'src/editors/base64.js',

'src/editors/radio.js',

// All the themes and iconlibs
'src/theme.js',
'src/themes/*.js',
Expand Down
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ So, the final order of properties in the form (and in returned JSON data) will b
### format

JSON Editor supports many different formats for schemas of type `string`. They will work with schemas of type `integer` and `number` as well, but some formats may produce weird results.
If the `enum` property is specified, `format` will be ignored.
If the `enum` property is specified, `format` will be limited to "radio" or "select" (default).

JSON Editor uses HTML5 input types, so some of these may render as basic text input in older browsers:

Expand Down Expand Up @@ -1032,10 +1032,9 @@ The following schema will now use this custom editor for each of the array eleme

If you create a custom editor interface that you think could be helpful to others, submit a pull request!

The possibilities are endless. Some ideas:
The possibilities are endless. Some ideas:

* A compact way to edit objects
* Radio button version of the `select` editor
* Autosuggest for strings (like enum, but not restricted to those values)
* Better editor for arrays of strings (tag editor)
* Canvas based image editor that produces Base64 data URLs
Expand Down
194 changes: 191 additions & 3 deletions dist/jsoneditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -5278,6 +5278,167 @@ JSONEditor.defaults.editors.base64 = JSONEditor.AbstractEditor.extend({
}
});

JSONEditor.defaults.editors.radio = JSONEditor.AbstractEditor.extend({
setValue: function(value,initial) {
value = this.typecast(value || '');

// Sanitize value before setting it
var sanitized = value;
if(this.schema.enum.indexOf(sanitized) < 0) {
sanitized = this.schema.enum[0];
}

if(this.value === sanitized) {
return;
}

var self = this;
$each(this.inputs,function(i,input) {
if (input.value === sanitized) {
input.checked = true;
self.value = sanitized;
self.jsoneditor.notifyWatchers(self.path);
return false;
}
});
},
register: function() {
this._super();
if(!this.inputs) return;
$each(this.inputs,function(i,input) {
input.setAttribute('name',this.formname);
});
},
unregister: function() {
this._super();
if(!this.inputs) return;
$each(this.inputs,function(i,input) {
input.removeAttribute('name');
});
},
getNumColumns: function() {
var longest_text = this.getTitle().length;
for(var i=0; i<this.schema.enum.length; i++) {
longest_text = Math.max(longest_text,this.schema.enum[i].length+4);
}
return Math.min(12,Math.max(longest_text/7,2));
},
typecast: function(value) {
if(this.schema.type === "boolean") {
return !!value;
}
else if(this.schema.type === "number") {
return 1*value;
}
else if(this.schema.type === "integer") {
return Math.floor(value*1);
}
else {
return ""+value;
}
},
getValue: function() {
return this.value;
},
removeProperty: function() {
this._super();
$each(this.inputs,function(i,input) {
input.style.display = 'none';
});
if(this.description) this.description.style.display = 'none';
this.theme.disableLabel(this.label);
},
addProperty: function() {
this._super();
$each(this.inputs,function(i,input) {
input.style.display = '';
});
if(this.description) this.description.style.display = '';
this.theme.enableLabel(this.label);
},
sanitize: function(value) {
if(this.schema.type === "number") {
return 1*value;
}
else if(this.schema.type === "integer") {
return Math.floor(value*1);
}
else {
return ""+value;
}
},
build: function() {
var self = this, i;
if(!this.getOption('compact',false)) this.header = this.label = this.theme.getFormInputLabel(this.getTitle());
if(this.schema.description) this.description = this.theme.getFormInputDescription(this.schema.description);

this.select_options = {};
this.select_values = {};

var e = this.schema.enum || [];
var options = [];
for(i=0; i<e.length; i++) {
// If the sanitized value is different from the enum value, don't include it
if(this.sanitize(e[i]) !== e[i]) continue;

options.push(e[i]+"");
this.select_values[e[i]+""] = e[i];
}

this.input_type = 'radiogroup';
this.inputs = {};
this.controls = {};
for(i=0; i<options.length; i++) {
this.inputs[options[i]] = this.theme.getRadio();
this.inputs[options[i]].setAttribute('value', options[i]);
this.inputs[options[i]].setAttribute('name', this.formname);
var label = this.theme.getRadioLabel(options[i]);
this.controls[options[i]] = this.theme.getFormControl(label, this.inputs[options[i]]);
}

this.control = this.theme.getRadioGroupHolder(this.controls,this.label,this.description);
this.container.appendChild(this.control);
this.control.addEventListener('change',function(e) {
e.preventDefault();
e.stopPropagation();

var val = e.target.value;

var sanitized = val;
if(self.schema.enum.indexOf(val) === -1) {
sanitized = self.schema.enum[0];
}

self.value = sanitized;

if(self.parent) self.parent.onChildEditorChange(self);
else self.jsoneditor.onChange();
self.jsoneditor.notifyWatchers(self.path);
});
},
enable: function() {
if(!this.always_disabled) {
$each(this.inputs,function(i,input) {
input.disabled = false;
});
}
this._super();
},
disable: function() {
$each(this.inputs,function(i,input) {
input.disabled = true;
});
this._super();
},
destroy: function() {
if(this.label) this.label.parentNode.removeChild(this.label);
if(this.description) this.description.parentNode.removeChild(this.description);
$each(this.inputs,function(i,input) {
input.parentNode.removeChild(input);
});
this._super();
}
});
JSONEditor.AbstractTheme = Class.extend({
getContainer: function() {
return document.createElement('div');
Expand Down Expand Up @@ -5379,6 +5540,34 @@ JSONEditor.AbstractTheme = Class.extend({

return el;
},
getRadio: function() {
var el = this.getFormInputField('radio');
el.style.display = 'inline-block';
el.style.width = 'auto';
return el;
},
getRadioGroupHolder: function(controls,label,description) {
var el = document.createElement('div');

if(label) {
label.style.display = 'block';
el.appendChild(label);
}
for(var i in controls) {
if(!controls.hasOwnProperty(i)) continue;
controls[i].style.display = 'inline-block';
controls[i].style.marginRight = '20px';
el.appendChild(controls[i]);
}

if(description) el.appendChild(description);
return el;
},
getRadioLabel: function(text) {
var el = this.getFormInputLabel(text);
el.style.fontWeight = 'normal';
return el;
},
getSelectInput: function(options) {
var select = document.createElement('select');
if(options) this.setSelectOptions(select, options);
Expand Down Expand Up @@ -5436,7 +5625,7 @@ JSONEditor.AbstractTheme = Class.extend({
var el = document.createElement('div');
el.className = 'form-control';
if(label) el.appendChild(label);
if(input.type === 'checkbox') {
if((input.type === 'checkbox') || (input.type === 'radio')) {
label.insertBefore(input,label.firstChild);
}
else {
Expand Down Expand Up @@ -6647,7 +6836,7 @@ JSONEditor.defaults.resolvers.unshift(function(schema) {
return "enum";
}
else if(schema.type === "number" || schema.type === "integer" || schema.type === "string") {
return "select";
return schema.format || "select";
}
}
});
Expand All @@ -6662,7 +6851,6 @@ JSONEditor.defaults.resolvers.unshift(function(schema) {
// If this schema uses `oneOf`
if(schema.oneOf) return "multiple";
});

/**
* This is a small wrapper for using JSON Editor like a typical jQuery plugin.
*/
Expand Down
4 changes: 2 additions & 2 deletions dist/jsoneditor.min.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions examples/basic.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ <h1>Basic JSON Editor Example</h1>
properties: {
make: {
type: "string",
format: "radio",
enum: [
"Toyota",
"BMW",
Expand Down
4 changes: 2 additions & 2 deletions src/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ JSONEditor.defaults.resolvers.unshift(function(schema) {
return "enum";
}
else if(schema.type === "number" || schema.type === "integer" || schema.type === "string") {
return "select";
return schema.format || "select";
}
}
});
Expand All @@ -82,4 +82,4 @@ JSONEditor.defaults.resolvers.unshift(function(schema) {
JSONEditor.defaults.resolvers.unshift(function(schema) {
// If this schema uses `oneOf`
if(schema.oneOf) return "multiple";
});
});
Loading