-1;
else if(this.jsoneditor.options.required_by_default) return true;
else return false;
},
getDisplayText: function(arr) {
var disp = [];
var used = {};
// Determine how many times each attribute name is used.
// This helps us pick the most distinct display text for the schemas.
$each(arr,function(i,el) {
if(el.title) {
used[el.title] = used[el.title] || 0;
used[el.title]++;
}
if(el.description) {
used[el.description] = used[el.description] || 0;
used[el.description]++;
}
if(el.format) {
used[el.format] = used[el.format] || 0;
used[el.format]++;
}
if(el.type) {
used[el.type] = used[el.type] || 0;
used[el.type]++;
}
});
// Determine display text for each element of the array
$each(arr,function(i,el) {
var name;
// If it's a simple string
if(typeof el === "string") name = el;
// Object
else if(el.title && used[el.title]<=1) name = el.title;
else if(el.format && used[el.format]<=1) name = el.format;
else if(el.type && used[el.type]<=1) name = el.type;
else if(el.description && used[el.description]<=1) name = el.descripton;
else if(el.title) name = el.title;
else if(el.format) name = el.format;
else if(el.type) name = el.type;
else if(el.description) name = el.description;
else if(JSON.stringify(el).length < 50) name = JSON.stringify(el);
else name = "type";
disp.push(name);
});
// Replace identical display text with "text 1", "text 2", etc.
var inc = {};
$each(disp,function(i,name) {
inc[name] = inc[name] || 0;
inc[name]++;
if(used[name] > 1) disp[i] = name + " " + inc[name];
});
return disp;
},
getOption: function(key) {
try {
throw "getOption is deprecated";
}
catch(e) {
window.console.error(e);
}
return this.options[key];
},
showValidationErrors: function(errors) {
}
});
JSONEditor.defaults.editors["null"] = JSONEditor.AbstractEditor.extend({
getValue: function() {
return null;
},
setValue: function() {
this.onChange();
},
getNumColumns: function() {
return 2;
}
});
JSONEditor.defaults.editors.string = JSONEditor.AbstractEditor.extend({
register: function() {
this._super();
if(!this.input) return;
this.input.setAttribute('name',this.formname);
},
unregister: function() {
this._super();
if(!this.input) return;
this.input.removeAttribute('name');
},
setValue: function(value,initial,from_template) {
var self = this;
if(this.template && !from_template) {
return;
}
if(value === null || typeof value === 'undefined') value = "";
else if(typeof value === "object") value = JSON.stringify(value);
else if(typeof value !== "string") value = ""+value;
if(value === this.serialized) return;
// Sanitize value before setting it
var sanitized = this.sanitize(value);
if(this.input.value === sanitized) {
return;
}
this.input.value = sanitized;
// If using SCEditor, update the WYSIWYG
if(this.sceditor_instance) {
this.sceditor_instance.val(sanitized);
}
else if(this.epiceditor) {
this.epiceditor.importFile(null,sanitized);
}
else if(this.ace_editor) {
this.ace_editor.setValue(sanitized);
}
var changed = from_template || this.getValue() !== value;
this.refreshValue();
if(initial) this.is_dirty = false;
else if(this.jsoneditor.options.show_errors === "change") this.is_dirty = true;
if(this.adjust_height) this.adjust_height(this.input);
// Bubble this setValue to parents if the value changed
this.onChange(changed);
},
getNumColumns: function() {
var min = Math.ceil(Math.max(this.getTitle().length,this.schema.maxLength||0,this.schema.minLength||0)/5);
var num;
if(this.input_type === 'textarea') num = 6;
else if(['text','email'].indexOf(this.input_type) >= 0) num = 4;
else num = 2;
return Math.min(12,Math.max(min,num));
},
build: function() {
var self = this, i;
if(!this.options.compact) this.header = this.label = this.theme.getFormInputLabel(this.getTitle());
if(this.schema.description) this.description = this.theme.getFormInputDescription(this.schema.description);
this.format = this.schema.format;
if(!this.format && this.schema.media && this.schema.media.type) {
this.format = this.schema.media.type.replace(/(^(application|text)\/(x-)?(script\.)?)|(-source$)/g,'');
}
if(!this.format && this.options.default_format) {
this.format = this.options.default_format;
}
if(this.options.format) {
this.format = this.options.format;
}
// Specific format
if(this.format) {
// Text Area
if(this.format === 'textarea') {
this.input_type = 'textarea';
this.input = this.theme.getTextareaInput();
}
// Range Input
else if(this.format === 'range') {
this.input_type = 'range';
var min = this.schema.minimum || 0;
var max = this.schema.maximum || Math.max(100,min+1);
var step = 1;
if(this.schema.multipleOf) {
if(min%this.schema.multipleOf) min = Math.ceil(min/this.schema.multipleOf)*this.schema.multipleOf;
if(max%this.schema.multipleOf) max = Math.floor(max/this.schema.multipleOf)*this.schema.multipleOf;
step = this.schema.multipleOf;
}
this.input = this.theme.getRangeInput(min,max,step);
}
// Source Code
else if([
'actionscript',
'batchfile',
'bbcode',
'c',
'c++',
'cpp',
'coffee',
'csharp',
'css',
'dart',
'django',
'ejs',
'erlang',
'golang',
'handlebars',
'haskell',
'haxe',
'html',
'ini',
'jade',
'java',
'javascript',
'json',
'less',
'lisp',
'lua',
'makefile',
'markdown',
'matlab',
'mysql',
'objectivec',
'pascal',
'perl',
'pgsql',
'php',
'python',
'r',
'ruby',
'sass',
'scala',
'scss',
'smarty',
'sql',
'stylus',
'svg',
'twig',
'vbscript',
'xml',
'yaml'
].indexOf(this.format) >= 0
) {
this.input_type = this.format;
this.source_code = true;
this.input = this.theme.getTextareaInput();
}
// HTML5 Input type
else {
this.input_type = this.format;
this.input = this.theme.getFormInputField(this.input_type);
}
}
// Normal text input
else {
this.input_type = 'text';
this.input = this.theme.getFormInputField(this.input_type);
}
// minLength, maxLength, and pattern
if(typeof this.schema.maxLength !== "undefined") this.input.setAttribute('maxlength',this.schema.maxLength);
if(typeof this.schema.pattern !== "undefined") this.input.setAttribute('pattern',this.schema.pattern);
else if(typeof this.schema.minLength !== "undefined") this.input.setAttribute('pattern','.{'+this.schema.minLength+',}');
if(this.options.compact) {
this.container.className += ' compact';
}
else {
if(this.options.input_width) this.input.style.width = this.options.input_width;
}
if(this.schema.readOnly || this.schema.readonly || this.schema.template) {
this.always_disabled = true;
this.input.disabled = true;
}
this.input
.addEventListener('change',function(e) {
e.preventDefault();
e.stopPropagation();
// Don't allow changing if this field is a template
if(self.schema.template) {
this.value = self.value;
return;
}
var val = this.value;
// sanitize value
var sanitized = self.sanitize(val);
if(val !== sanitized) {
this.value = sanitized;
}
self.is_dirty = true;
self.refreshValue();
self.onChange(true);
});
if(this.options.input_height) this.input.style.height = this.options.input_height;
if(this.options.expand_height) {
this.adjust_height = function(el) {
if(!el) return;
var i, ch=el.offsetHeight;
// Input too short
if(el.offsetHeight < el.scrollHeight) {
i=0;
while(el.offsetHeight < el.scrollHeight+3) {
if(i>100) break;
i++;
ch++;
el.style.height = ch+'px';
}
}
else {
i=0;
while(el.offsetHeight >= el.scrollHeight+3) {
if(i>100) break;
i++;
ch--;
el.style.height = ch+'px';
}
el.style.height = (ch+1)+'px';
}
};
this.input.addEventListener('keyup',function(e) {
self.adjust_height(this);
});
this.input.addEventListener('change',function(e) {
self.adjust_height(this);
});
this.adjust_height();
}
if(this.format) this.input.setAttribute('data-schemaformat',this.format);
this.control = this.theme.getFormControl(this.label, this.input, this.description);
this.container.appendChild(this.control);
// Any special formatting that needs to happen after the input is added to the dom
window.requestAnimationFrame(function() {
// Skip in case the input is only a temporary editor,
// otherwise, in the case of an ace_editor creation,
// it will generate an error trying to append it to the missing parentNode
if(self.input.parentNode) self.afterInputReady();
if(self.adjust_height) self.adjust_height(self.input);
});
// Compile and store the template
if(this.schema.template) {
this.template = this.jsoneditor.compileTemplate(this.schema.template, this.template_engine);
this.refreshValue();
}
else {
this.refreshValue();
}
},
enable: function() {
if(!this.always_disabled) {
this.input.disabled = false;
// TODO: WYSIWYG and Markdown editors
}
this._super();
},
disable: function() {
this.input.disabled = true;
// TODO: WYSIWYG and Markdown editors
this._super();
},
afterInputReady: function() {
var self = this, options;
// Code editor
if(this.source_code) {
// WYSIWYG html and bbcode editor
if(this.options.wysiwyg &&
['html','bbcode'].indexOf(this.input_type) >= 0 &&
window.jQuery && window.jQuery.fn && window.jQuery.fn.sceditor
) {
options = $extend({},{
plugins: self.input_type==='html'? 'xhtml' : 'bbcode',
emoticonsEnabled: false,
width: '100%',
height: 300
},JSONEditor.plugins.sceditor,self.options.sceditor_options||{});
window.jQuery(self.input).sceditor(options);
self.sceditor_instance = window.jQuery(self.input).sceditor('instance');
self.sceditor_instance.blur(function() {
// Get editor's value
var val = window.jQuery(""+self.sceditor_instance.val()+"
");
// Remove sceditor spans/divs
window.jQuery('#sceditor-start-marker,#sceditor-end-marker,.sceditor-nlf',val).remove();
// Set the value and update
self.input.value = val.html();
self.value = self.input.value;
self.is_dirty = true;
self.onChange(true);
});
}
// EpicEditor for markdown (if it's loaded)
else if (this.input_type === 'markdown' && window.EpicEditor) {
this.epiceditor_container = document.createElement('div');
this.input.parentNode.insertBefore(this.epiceditor_container,this.input);
this.input.style.display = 'none';
options = $extend({},JSONEditor.plugins.epiceditor,{
container: this.epiceditor_container,
clientSideStorage: false
});
this.epiceditor = new window.EpicEditor(options).load();
this.epiceditor.importFile(null,this.getValue());
this.epiceditor.on('update',function() {
var val = self.epiceditor.exportFile();
self.input.value = val;
self.value = val;
self.is_dirty = true;
self.onChange(true);
});
}
// ACE editor for everything else
else if(window.ace) {
var mode = this.input_type;
// aliases for c/cpp
if(mode === 'cpp' || mode === 'c++' || mode === 'c') {
mode = 'c_cpp';
}
this.ace_container = document.createElement('div');
this.ace_container.style.width = '100%';
this.ace_container.style.position = 'relative';
this.ace_container.style.height = '400px';
this.input.parentNode.insertBefore(this.ace_container,this.input);
this.input.style.display = 'none';
this.ace_editor = window.ace.edit(this.ace_container);
this.ace_editor.setValue(this.getValue());
// The theme
if(JSONEditor.plugins.ace.theme) this.ace_editor.setTheme('ace/theme/'+JSONEditor.plugins.ace.theme);
// The mode
mode = window.ace.require("ace/mode/"+mode);
if(mode) this.ace_editor.getSession().setMode(new mode.Mode());
// Listen for changes
this.ace_editor.on('change',function() {
var val = self.ace_editor.getValue();
self.input.value = val;
self.refreshValue();
self.is_dirty = true;
self.onChange(true);
});
}
}
self.theme.afterInputReady(self.input);
},
refreshValue: function() {
this.value = this.input.value;
if(typeof this.value !== "string") this.value = '';
this.serialized = this.value;
},
destroy: function() {
// If using SCEditor, destroy the editor instance
if(this.sceditor_instance) {
this.sceditor_instance.destroy();
}
else if(this.epiceditor) {
this.epiceditor.unload();
}
else if(this.ace_editor) {
this.ace_editor.destroy();
}
this.template = null;
if(this.input && this.input.parentNode) this.input.parentNode.removeChild(this.input);
if(this.label && this.label.parentNode) this.label.parentNode.removeChild(this.label);
if(this.description && this.description.parentNode) this.description.parentNode.removeChild(this.description);
this._super();
},
/**
* This is overridden in derivative editors
*/
sanitize: function(value) {
return value;
},
/**
* Re-calculates the value if needed
*/
onWatchedFieldChange: function() {
var self = this, vars, j;
// If this editor needs to be rendered by a macro template
if(this.template) {
vars = this.getWatchedFieldValues();
this.setValue(this.template(vars),false,true);
}
this._super();
},
showValidationErrors: function(errors) {
var self = this;
if(this.jsoneditor.options.show_errors === "always") {}
else if(!this.is_dirty && this.previous_error_setting===this.jsoneditor.options.show_errors) return;
this.previous_error_setting = this.jsoneditor.options.show_errors;
var messages = [];
$each(errors,function(i,error) {
if(error.path === self.path) {
messages.push(error.message);
}
});
if(messages.length) {
this.theme.addInputError(this.input, messages.join('. ')+'.');
}
else {
this.theme.removeInputError(this.input);
}
}
});
JSONEditor.defaults.editors.number = JSONEditor.defaults.editors.string.extend({
sanitize: function(value) {
return (value+"").replace(/[^0-9\.\-eE]/g,'');
},
getNumColumns: function() {
return 2;
},
getValue: function() {
return this.value*1;
}
});
JSONEditor.defaults.editors.integer = JSONEditor.defaults.editors.number.extend({
sanitize: function(value) {
value = value + "";
return value.replace(/[^0-9\-]/g,'');
},
getNumColumns: function() {
return 2;
}
});
JSONEditor.defaults.editors.object = JSONEditor.AbstractEditor.extend({
getDefault: function() {
return $extend({},this.schema["default"] || {});
},
getChildEditors: function() {
return this.editors;
},
register: function() {
this._super();
if(this.editors) {
for(var i in this.editors) {
if(!this.editors.hasOwnProperty(i)) continue;
this.editors[i].register();
}
}
},
unregister: function() {
this._super();
if(this.editors) {
for(var i in this.editors) {
if(!this.editors.hasOwnProperty(i)) continue;
this.editors[i].unregister();
}
}
},
getNumColumns: function() {
return Math.max(Math.min(12,this.maxwidth),3);
},
enable: function() {
if(this.editjson_button) this.editjson_button.disabled = false;
if(this.addproperty_button) this.addproperty_button.disabled = false;
this._super();
if(this.editors) {
for(var i in this.editors) {
if(!this.editors.hasOwnProperty(i)) continue;
this.editors[i].enable();
}
}
},
disable: function() {
if(this.editjson_button) this.editjson_button.disabled = true;
if(this.addproperty_button) this.addproperty_button.disabled = true;
this.hideEditJSON();
this._super();
if(this.editors) {
for(var i in this.editors) {
if(!this.editors.hasOwnProperty(i)) continue;
this.editors[i].disable();
}
}
},
layoutEditors: function() {
var self = this, i, j;
if(!this.row_container) return;
// Sort editors by propertyOrder
this.property_order = Object.keys(this.editors);
this.property_order = this.property_order.sort(function(a,b) {
var ordera = self.editors[a].schema.propertyOrder;
var orderb = self.editors[b].schema.propertyOrder;
if(typeof ordera !== "number") ordera = 1000;
if(typeof orderb !== "number") orderb = 1000;
return ordera - orderb;
});
var container;
if(this.format === 'grid') {
var rows = [];
$each(this.property_order, function(j,key) {
var editor = self.editors[key];
if(editor.property_removed) return;
var found = false;
var width = editor.options.hidden? 0 : (editor.options.grid_columns || editor.getNumColumns());
var height = editor.options.hidden? 0 : editor.container.offsetHeight;
// See if the editor will fit in any of the existing rows first
for(var i=0; i height)) {
found = i;
}
}
}
// If there isn't a spot in any of the existing rows, start a new row
if(found === false) {
rows.push({
width: 0,
minh: 999999,
maxh: 0,
editors: []
});
found = rows.length-1;
}
rows[found].editors.push({
key: key,
//editor: editor,
width: width,
height: height
});
rows[found].width += width;
rows[found].minh = Math.min(rows[found].minh,height);
rows[found].maxh = Math.max(rows[found].maxh,height);
});
// Make almost full rows width 12
// Do this by increasing all editors' sizes proprotionately
// Any left over space goes to the biggest editor
// Don't touch rows with a width of 6 or less
for(i=0; i rows[i].editors[biggest].width) biggest = j;
rows[i].editors[j].width *= 12/rows[i].width;
rows[i].editors[j].width = Math.floor(rows[i].editors[j].width);
new_width += rows[i].editors[j].width;
}
if(new_width < 12) rows[i].editors[biggest].width += 12-new_width;
rows[i].width = 12;
}
}
// layout hasn't changed
if(this.layout === JSON.stringify(rows)) return false;
this.layout = JSON.stringify(rows);
// Layout the form
container = document.createElement('div');
for(i=0; i= this.schema.maxProperties);
if(this.addproperty_checkboxes) {
this.addproperty_list.innerHTML = '';
}
this.addproperty_checkboxes = {};
// Check for which editors can't be removed or added back
for(i in this.cached_editors) {
if(!this.cached_editors.hasOwnProperty(i)) continue;
this.addPropertyCheckbox(i);
if(this.isRequired(this.cached_editors[i]) && i in this.editors) {
this.addproperty_checkboxes[i].disabled = true;
}
if(typeof this.schema.minProperties !== "undefined" && num_props <= this.schema.minProperties) {
this.addproperty_checkboxes[i].disabled = this.addproperty_checkboxes[i].checked;
if(!this.addproperty_checkboxes[i].checked) show_modal = true;
}
else if(!(i in this.editors)) {
if(!can_add && !this.schema.properties.hasOwnProperty(i)) {
this.addproperty_checkboxes[i].disabled = true;
}
else {
this.addproperty_checkboxes[i].disabled = false;
show_modal = true;
}
}
else {
show_modal = true;
can_remove = true;
}
}
if(this.canHaveAdditionalProperties()) {
show_modal = true;
}
// Additional addproperty checkboxes not tied to a current editor
for(i in this.schema.properties) {
if(!this.schema.properties.hasOwnProperty(i)) continue;
if(this.cached_editors[i]) continue;
show_modal = true;
this.addPropertyCheckbox(i);
}
// If no editors can be added or removed, hide the modal button
if(!show_modal) {
this.hideAddProperty();
this.addproperty_controls.style.display = 'none';
}
// If additional properties are disabled
else if(!this.canHaveAdditionalProperties()) {
this.addproperty_add.style.display = 'none';
this.addproperty_input.style.display = 'none';
}
// If no new properties can be added
else if(!can_add) {
this.addproperty_add.disabled = true;
}
// If new properties can be added
else {
this.addproperty_add.disabled = false;
}
},
isRequired: function(editor) {
if(typeof editor.schema.required === "boolean") return editor.schema.required;
else if(Array.isArray(this.schema.required)) return this.schema.required.indexOf(editor.key) > -1;
else if(this.jsoneditor.options.required_by_default) return true;
else return false;
},
setValue: function(value, initial) {
var self = this;
value = value || {};
if(typeof value !== "object" || Array.isArray(value)) value = {};
// First, set the values for all of the defined properties
$each(this.cached_editors, function(i,editor) {
// Value explicitly set
if(typeof value[i] !== "undefined") {
self.addObjectProperty(i);
editor.setValue(value[i],initial);
}
// Otherwise, remove value unless this is the initial set or it's required
else if(!initial && !self.isRequired(editor)) {
self.removeObjectProperty(i);
}
// Otherwise, set the value to the default
else {
editor.setValue(editor.getDefault(),initial);
}
});
$each(value, function(i,val) {
if(!self.cached_editors[i]) {
self.addObjectProperty(i);
if(self.editors[i]) self.editors[i].setValue(val,initial);
}
});
this.refreshValue();
this.layoutEditors();
this.onChange();
},
showValidationErrors: function(errors) {
var self = this;
// Get all the errors that pertain to this editor
var my_errors = [];
var other_errors = [];
$each(errors, function(i,error) {
if(error.path === self.path) {
my_errors.push(error);
}
else {
other_errors.push(error);
}
});
// Show errors for this editor
if(this.error_holder) {
if(my_errors.length) {
var message = [];
this.error_holder.innerHTML = '';
this.error_holder.style.display = '';
$each(my_errors, function(i,error) {
self.error_holder.appendChild(self.theme.getErrorMessage(error.message));
});
}
// Hide error area
else {
this.error_holder.style.display = 'none';
}
}
// Show error for the table row if this is inside a table
if(this.options.table_row) {
if(my_errors.length) {
this.theme.addTableRowError(this.container);
}
else {
this.theme.removeTableRowError(this.container);
}
}
// Show errors for child editors
$each(this.editors, function(i,editor) {
editor.showValidationErrors(other_errors);
});
}
});
JSONEditor.defaults.editors.array = JSONEditor.AbstractEditor.extend({
getDefault: function() {
return this.schema["default"] || [];
},
register: function() {
this._super();
if(this.rows) {
for(var i=0; i= this.schema.items.length) {
if(this.schema.additionalItems===true) {
return {};
}
else if(this.schema.additionalItems) {
return $extend({},this.schema.additionalItems);
}
}
else {
return $extend({},this.schema.items[i]);
}
}
else if(this.schema.items) {
return $extend({},this.schema.items);
}
else {
return {};
}
},
getItemInfo: function(i) {
var schema = this.getItemSchema(i);
// Check if it's cached
this.item_info = this.item_info || {};
var stringified = JSON.stringify(schema);
if(typeof this.item_info[stringified] !== "undefined") return this.item_info[stringified];
// Get the schema for this item
schema = this.jsoneditor.expandRefs(schema);
this.item_info[stringified] = {
title: schema.title || "item",
'default': schema["default"],
width: 12,
child_editors: schema.properties || schema.items
};
return this.item_info[stringified];
},
getElementEditor: function(i) {
var item_info = this.getItemInfo(i);
var schema = this.getItemSchema(i);
schema = this.jsoneditor.expandRefs(schema);
schema.title = item_info.title+' '+(i+1);
var editor = this.jsoneditor.getEditorClass(schema);
var holder;
if(this.tabs_holder) {
holder = this.theme.getTabContent();
}
else if(item_info.child_editors) {
holder = this.theme.getChildEditorHolder();
}
else {
holder = this.theme.getIndentedPanel();
}
this.row_holder.appendChild(holder);
var ret = this.jsoneditor.createEditor(editor,{
jsoneditor: this.jsoneditor,
schema: schema,
container: holder,
path: this.path+'.'+i,
parent: this,
required: true
});
ret.preBuild();
ret.build();
ret.postBuild();
if(!ret.title_controls) {
ret.array_controls = this.theme.getButtonHolder();
holder.appendChild(ret.array_controls);
}
return ret;
},
destroy: function() {
this.empty(true);
if(this.title && this.title.parentNode) this.title.parentNode.removeChild(this.title);
if(this.description && this.description.parentNode) this.description.parentNode.removeChild(this.description);
if(this.row_holder && this.row_holder.parentNode) this.row_holder.parentNode.removeChild(this.row_holder);
if(this.controls && this.controls.parentNode) this.controls.parentNode.removeChild(this.controls);
if(this.panel && this.panel.parentNode) this.panel.parentNode.removeChild(this.panel);
this.rows = this.row_cache = this.title = this.description = this.row_holder = this.panel = this.controls = null;
this._super();
},
empty: function(hard) {
if(!this.rows) return;
var self = this;
$each(this.rows,function(i,row) {
if(hard) {
if(row.tab && row.tab.parentNode) row.tab.parentNode.removeChild(row.tab);
self.destroyRow(row,true);
self.row_cache[i] = null;
}
self.rows[i] = null;
});
self.rows = [];
if(hard) self.row_cache = [];
},
destroyRow: function(row,hard) {
var holder = row.container;
if(hard) {
row.destroy();
if(holder.parentNode) holder.parentNode.removeChild(holder);
if(row.tab && row.tab.parentNode) row.tab.parentNode.removeChild(row.tab);
}
else {
if(row.tab) row.tab.style.display = 'none';
holder.style.display = 'none';
row.unregister();
}
},
getMax: function() {
if((Array.isArray(this.schema.items)) && this.schema.additionalItems === false) {
return Math.min(this.schema.items.length,this.schema.maxItems || Infinity);
}
else {
return this.schema.maxItems || Infinity;
}
},
refreshTabs: function(refresh_headers) {
var self = this;
$each(this.rows, function(i,row) {
if(!row.tab) return;
if(refresh_headers) {
row.tab_text.textContent = row.getHeaderText();
}
else {
if(row.tab === self.active_tab) {
self.theme.markTabActive(row.tab);
row.container.style.display = '';
}
else {
self.theme.markTabInactive(row.tab);
row.container.style.display = 'none';
}
}
});
},
setValue: function(value, initial) {
// Update the array's value, adding/removing rows when necessary
value = value || [];
if(!(Array.isArray(value))) value = [value];
var serialized = JSON.stringify(value);
if(serialized === this.serialized) return;
// Make sure value has between minItems and maxItems items in it
if(this.schema.minItems) {
while(value.length < this.schema.minItems) {
value.push(this.getItemInfo(value.length)["default"]);
}
}
if(this.getMax() && value.length > this.getMax()) {
value = value.slice(0,this.getMax());
}
var self = this;
$each(value,function(i,val) {
if(self.rows[i]) {
// TODO: don't set the row's value if it hasn't changed
self.rows[i].setValue(val,initial);
}
else if(self.row_cache[i]) {
self.rows[i] = self.row_cache[i];
self.rows[i].setValue(val,initial);
self.rows[i].container.style.display = '';
if(self.rows[i].tab) self.rows[i].tab.style.display = '';
self.rows[i].register();
}
else {
self.addRow(val,initial);
}
});
for(var j=value.length; j= this.rows.length;
$each(this.rows,function(i,editor) {
// Hide the move down button for the last row
if(editor.movedown_button) {
if(i === self.rows.length - 1) {
editor.movedown_button.style.display = 'none';
}
else {
editor.movedown_button.style.display = '';
}
}
// Hide the delete button if we have minItems items
if(editor.delete_button) {
if(minItems) {
editor.delete_button.style.display = 'none';
}
else {
editor.delete_button.style.display = '';
}
}
// Get the value for this editor
self.value[i] = editor.getValue();
});
var controls_needed = false;
if(!this.value.length) {
this.delete_last_row_button.style.display = 'none';
this.remove_all_rows_button.style.display = 'none';
}
else if(this.value.length === 1) {
this.remove_all_rows_button.style.display = 'none';
// If there are minItems items in the array, hide the delete button beneath the rows
if(minItems || this.hide_delete_buttons) {
this.delete_last_row_button.style.display = 'none';
}
else {
this.delete_last_row_button.style.display = '';
controls_needed = true;
}
}
else {
// If there are minItems items in the array, hide the delete button beneath the rows
if(minItems || this.hide_delete_buttons) {
this.delete_last_row_button.style.display = 'none';
this.remove_all_rows_button.style.display = 'none';
}
else {
this.delete_last_row_button.style.display = '';
this.remove_all_rows_button.style.display = '';
controls_needed = true;
}
}
// If there are maxItems in the array, hide the add button beneath the rows
if((this.getMax() && this.getMax() <= this.rows.length) || this.hide_add_button){
this.add_row_button.style.display = 'none';
}
else {
this.add_row_button.style.display = '';
controls_needed = true;
}
if(!this.collapsed && controls_needed) {
this.controls.style.display = 'inline-block';
}
else {
this.controls.style.display = 'none';
}
}
},
addRow: function(value, initial) {
var self = this;
var i = this.rows.length;
self.rows[i] = this.getElementEditor(i);
self.row_cache[i] = self.rows[i];
if(self.tabs_holder) {
self.rows[i].tab_text = document.createElement('span');
self.rows[i].tab_text.textContent = self.rows[i].getHeaderText();
self.rows[i].tab = self.theme.getTab(self.rows[i].tab_text);
self.rows[i].tab.addEventListener('click', function(e) {
self.active_tab = self.rows[i].tab;
self.refreshTabs();
e.preventDefault();
e.stopPropagation();
});
self.theme.addTab(self.tabs_holder, self.rows[i].tab);
}
var controls_holder = self.rows[i].title_controls || self.rows[i].array_controls;
// Buttons to delete row, move row up, and move row down
if(!self.hide_delete_buttons) {
self.rows[i].delete_button = this.getButton(self.getItemTitle(),'delete','Delete '+self.getItemTitle());
self.rows[i].delete_button.className += ' delete';
self.rows[i].delete_button.setAttribute('data-i',i);
self.rows[i].delete_button.addEventListener('click',function(e) {
e.preventDefault();
e.stopPropagation();
var i = this.getAttribute('data-i')*1;
var value = self.getValue();
var newval = [];
var new_active_tab = null;
$each(value,function(j,row) {
if(j===i) {
// If the one we're deleting is the active tab
if(self.rows[j].tab === self.active_tab) {
// Make the next tab active if there is one
// Note: the next tab is going to be the current tab after deletion
if(self.rows[j+1]) new_active_tab = self.rows[j].tab;
// Otherwise, make the previous tab active if there is one
else if(j) new_active_tab = self.rows[j-1].tab;
}
return; // If this is the one we're deleting
}
newval.push(row);
});
self.setValue(newval);
if(new_active_tab) {
self.active_tab = new_active_tab;
self.refreshTabs();
}
self.onChange(true);
});
if(controls_holder) {
controls_holder.appendChild(self.rows[i].delete_button);
}
}
if(i && !self.hide_move_buttons) {
self.rows[i].moveup_button = this.getButton('','moveup','Move up');
self.rows[i].moveup_button.className += ' moveup';
self.rows[i].moveup_button.setAttribute('data-i',i);
self.rows[i].moveup_button.addEventListener('click',function(e) {
e.preventDefault();
e.stopPropagation();
var i = this.getAttribute('data-i')*1;
if(i<=0) return;
var rows = self.getValue();
var tmp = rows[i-1];
rows[i-1] = rows[i];
rows[i] = tmp;
self.setValue(rows);
self.active_tab = self.rows[i-1].tab;
self.refreshTabs();
self.onChange(true);
});
if(controls_holder) {
controls_holder.appendChild(self.rows[i].moveup_button);
}
}
if(!self.hide_move_buttons) {
self.rows[i].movedown_button = this.getButton('','movedown','Move down');
self.rows[i].movedown_button.className += ' movedown';
self.rows[i].movedown_button.setAttribute('data-i',i);
self.rows[i].movedown_button.addEventListener('click',function(e) {
e.preventDefault();
e.stopPropagation();
var i = this.getAttribute('data-i')*1;
var rows = self.getValue();
if(i>=rows.length-1) return;
var tmp = rows[i+1];
rows[i+1] = rows[i];
rows[i] = tmp;
self.setValue(rows);
self.active_tab = self.rows[i+1].tab;
self.refreshTabs();
self.onChange(true);
});
if(controls_holder) {
controls_holder.appendChild(self.rows[i].movedown_button);
}
}
if(value) self.rows[i].setValue(value, initial);
self.refreshTabs();
},
addControls: function() {
var self = this;
this.collapsed = false;
this.toggle_button = this.getButton('','collapse','-');
this.title_controls.appendChild(this.toggle_button);
var row_holder_display = self.row_holder.style.display;
var controls_display = self.controls.style.display;
this.toggle_button.addEventListener('click',function(e) {
e.preventDefault();
e.stopPropagation();
if(self.collapsed) {
self.collapsed = false;
if(self.panel) self.panel.style.display = '';
self.row_holder.style.display = row_holder_display;
if(self.tabs_holder) self.tabs_holder.style.display = '';
self.controls.style.display = controls_display;
self.setButtonText(this,'','collapse','-');
}
else {
self.collapsed = true;
self.row_holder.style.display = 'none';
if(self.tabs_holder) self.tabs_holder.style.display = 'none';
self.controls.style.display = 'none';
if(self.panel) self.panel.style.display = 'none';
self.setButtonText(this,'','expand','+');
}
});
// If it should start collapsed
if(this.options.collapsed) {
$trigger(this.toggle_button,'click');
}
// Collapse button disabled
if(this.schema.options && typeof this.schema.options.disable_collapse !== "undefined") {
if(this.schema.options.disable_collapse) this.toggle_button.style.display = 'none';
}
else if(this.jsoneditor.options.disable_collapse) {
this.toggle_button.style.display = 'none';
}
// Add "new row" and "delete last" buttons below editor
this.add_row_button = this.getButton(this.getItemTitle(),'add','Add '+this.getItemTitle());
this.add_row_button.addEventListener('click',function(e) {
e.preventDefault();
e.stopPropagation();
var i = self.rows.length;
if(self.row_cache[i]) {
self.rows[i] = self.row_cache[i];
self.rows[i].setValue(self.rows[i].getDefault());
self.rows[i].container.style.display = '';
if(self.rows[i].tab) self.rows[i].tab.style.display = '';
self.rows[i].register();
}
else {
self.addRow();
}
self.active_tab = self.rows[i].tab;
self.refreshTabs();
self.refreshValue();
self.onChange(true);
});
self.controls.appendChild(this.add_row_button);
this.delete_last_row_button = this.getButton('Last '+this.getItemTitle(),'delete','Delete Last '+this.getItemTitle());
this.delete_last_row_button.addEventListener('click',function(e) {
e.preventDefault();
e.stopPropagation();
var rows = self.getValue();
var new_active_tab = null;
if(self.rows.length > 1 && self.rows[self.rows.length-1].tab === self.active_tab) new_active_tab = self.rows[self.rows.length-2].tab;
rows.pop();
self.setValue(rows);
if(new_active_tab) {
self.active_tab = new_active_tab;
self.refreshTabs();
}
self.onChange(true);
});
self.controls.appendChild(this.delete_last_row_button);
this.remove_all_rows_button = this.getButton('All','delete','Delete All');
this.remove_all_rows_button.addEventListener('click',function(e) {
e.preventDefault();
e.stopPropagation();
self.setValue([]);
self.onChange(true);
});
self.controls.appendChild(this.remove_all_rows_button);
if(self.tabs) {
this.add_row_button.style.width = '100%';
this.add_row_button.style.textAlign = 'left';
this.add_row_button.style.marginBottom = '3px';
this.delete_last_row_button.style.width = '100%';
this.delete_last_row_button.style.textAlign = 'left';
this.delete_last_row_button.style.marginBottom = '3px';
this.remove_all_rows_button.style.width = '100%';
this.remove_all_rows_button.style.textAlign = 'left';
this.remove_all_rows_button.style.marginBottom = '3px';
}
},
showValidationErrors: function(errors) {
var self = this;
// Get all the errors that pertain to this editor
var my_errors = [];
var other_errors = [];
$each(errors, function(i,error) {
if(error.path === self.path) {
my_errors.push(error);
}
else {
other_errors.push(error);
}
});
// Show errors for this editor
if(this.error_holder) {
if(my_errors.length) {
var message = [];
this.error_holder.innerHTML = '';
this.error_holder.style.display = '';
$each(my_errors, function(i,error) {
self.error_holder.appendChild(self.theme.getErrorMessage(error.message));
});
}
// Hide error area
else {
this.error_holder.style.display = 'none';
}
}
// Show errors for child editors
$each(this.rows, function(i,row) {
row.showValidationErrors(other_errors);
});
}
});
JSONEditor.defaults.editors.table = JSONEditor.defaults.editors.array.extend({
register: function() {
this._super();
if(this.rows) {
for(var i=0; i this.schema.maxItems) {
value = value.slice(0,this.schema.maxItems);
}
var serialized = JSON.stringify(value);
if(serialized === this.serialized) return;
var numrows_changed = false;
var self = this;
$each(value,function(i,val) {
if(self.rows[i]) {
// TODO: don't set the row's value if it hasn't changed
self.rows[i].setValue(val);
}
else {
self.addRow(val);
numrows_changed = true;
}
});
for(var j=value.length; j= this.rows.length;
var need_row_buttons = false;
$each(this.rows,function(i,editor) {
// Hide the move down button for the last row
if(editor.movedown_button) {
if(i === self.rows.length - 1) {
editor.movedown_button.style.display = 'none';
}
else {
need_row_buttons = true;
editor.movedown_button.style.display = '';
}
}
// Hide the delete button if we have minItems items
if(editor.delete_button) {
if(minItems) {
editor.delete_button.style.display = 'none';
}
else {
need_row_buttons = true;
editor.delete_button.style.display = '';
}
}
if(editor.moveup_button) {
need_row_buttons = true;
}
});
// Show/hide controls column in table
$each(this.rows,function(i,editor) {
if(need_row_buttons) {
editor.controls_cell.style.display = '';
}
else {
editor.controls_cell.style.display = 'none';
}
});
if(need_row_buttons) {
this.controls_header_cell.style.display = '';
}
else {
this.controls_header_cell.style.display = 'none';
}
var controls_needed = false;
if(!this.value.length) {
this.delete_last_row_button.style.display = 'none';
this.remove_all_rows_button.style.display = 'none';
this.table.style.display = 'none';
}
else if(this.value.length === 1 || this.hide_delete_buttons) {
this.table.style.display = '';
this.remove_all_rows_button.style.display = 'none';
// If there are minItems items in the array, hide the delete button beneath the rows
if(minItems || this.hide_delete_buttons) {
this.delete_last_row_button.style.display = 'none';
}
else {
this.delete_last_row_button.style.display = '';
controls_needed = true;
}
}
else {
this.table.style.display = '';
// If there are minItems items in the array, hide the delete button beneath the rows
if(minItems || this.hide_delete_buttons) {
this.delete_last_row_button.style.display = 'none';
this.remove_all_rows_button.style.display = 'none';
}
else {
this.delete_last_row_button.style.display = '';
this.remove_all_rows_button.style.display = '';
controls_needed = true;
}
}
// If there are maxItems in the array, hide the add button beneath the rows
if((this.schema.maxItems && this.schema.maxItems <= this.rows.length) || this.hide_add_button) {
this.add_row_button.style.display = 'none';
}
else {
this.add_row_button.style.display = '';
controls_needed = true;
}
if(!controls_needed) {
this.controls.style.display = 'none';
}
else {
this.controls.style.display = '';
}
},
refreshValue: function() {
var self = this;
this.value = [];
$each(this.rows,function(i,editor) {
// Get the value for this editor
self.value[i] = editor.getValue();
});
this.serialized = JSON.stringify(this.value);
},
addRow: function(value) {
var self = this;
var i = this.rows.length;
self.rows[i] = this.getElementEditor(i);
var controls_holder = self.rows[i].table_controls;
// Buttons to delete row, move row up, and move row down
if(!this.hide_delete_buttons) {
self.rows[i].delete_button = this.getButton('','delete','Delete');
self.rows[i].delete_button.className += ' delete';
self.rows[i].delete_button.setAttribute('data-i',i);
self.rows[i].delete_button.addEventListener('click',function(e) {
e.preventDefault();
e.stopPropagation();
var i = this.getAttribute('data-i')*1;
var value = self.getValue();
var newval = [];
$each(value,function(j,row) {
if(j===i) return; // If this is the one we're deleting
newval.push(row);
});
self.setValue(newval);
self.onChange(true);
});
controls_holder.appendChild(self.rows[i].delete_button);
}
if(i && !this.hide_move_buttons) {
self.rows[i].moveup_button = this.getButton('','moveup','Move up');
self.rows[i].moveup_button.className += ' moveup';
self.rows[i].moveup_button.setAttribute('data-i',i);
self.rows[i].moveup_button.addEventListener('click',function(e) {
e.preventDefault();
e.stopPropagation();
var i = this.getAttribute('data-i')*1;
if(i<=0) return;
var rows = self.getValue();
var tmp = rows[i-1];
rows[i-1] = rows[i];
rows[i] = tmp;
self.setValue(rows);
self.onChange(true);
});
controls_holder.appendChild(self.rows[i].moveup_button);
}
if(!this.hide_move_buttons) {
self.rows[i].movedown_button = this.getButton('','movedown','Move down');
self.rows[i].movedown_button.className += ' movedown';
self.rows[i].movedown_button.setAttribute('data-i',i);
self.rows[i].movedown_button.addEventListener('click',function(e) {
e.preventDefault();
e.stopPropagation();
var i = this.getAttribute('data-i')*1;
var rows = self.getValue();
if(i>=rows.length-1) return;
var tmp = rows[i+1];
rows[i+1] = rows[i];
rows[i] = tmp;
self.setValue(rows);
self.onChange(true);
});
controls_holder.appendChild(self.rows[i].movedown_button);
}
if(value) self.rows[i].setValue(value);
},
addControls: function() {
var self = this;
this.collapsed = false;
this.toggle_button = this.getButton('','collapse','-');
if(this.title_controls) {
this.title_controls.appendChild(this.toggle_button);
this.toggle_button.addEventListener('click',function(e) {
e.preventDefault();
e.stopPropagation();
if(self.collapsed) {
self.collapsed = false;
self.panel.style.display = '';
self.setButtonText(this,'','collapse','-');
}
else {
self.collapsed = true;
self.panel.style.display = 'none';
self.setButtonText(this,'','expand','+');
}
});
// If it should start collapsed
if(this.options.collapsed) {
$trigger(this.toggle_button,'click');
}
// Collapse button disabled
if(this.schema.options && typeof this.schema.options.disable_collapse !== "undefined") {
if(this.schema.options.disable_collapse) this.toggle_button.style.display = 'none';
}
else if(this.jsoneditor.options.disable_collapse) {
this.toggle_button.style.display = 'none';
}
}
// Add "new row" and "delete last" buttons below editor
this.add_row_button = this.getButton(this.getItemTitle(),'add','Add '+this.getItemTitle());
this.add_row_button.addEventListener('click',function(e) {
e.preventDefault();
e.stopPropagation();
self.addRow();
self.refreshValue();
self.refreshRowButtons();
self.onChange(true);
});
self.controls.appendChild(this.add_row_button);
this.delete_last_row_button = this.getButton('Last '+this.getItemTitle(),'delete','Delete Last '+this.getItemTitle());
this.delete_last_row_button.addEventListener('click',function(e) {
e.preventDefault();
e.stopPropagation();
var rows = self.getValue();
rows.pop();
self.setValue(rows);
self.onChange(true);
});
self.controls.appendChild(this.delete_last_row_button);
this.remove_all_rows_button = this.getButton('All','delete','Delete All');
this.remove_all_rows_button.addEventListener('click',function(e) {
e.preventDefault();
e.stopPropagation();
self.setValue([]);
self.onChange(true);
});
self.controls.appendChild(this.remove_all_rows_button);
}
});
// Multiple Editor (for when `type` is an array)
JSONEditor.defaults.editors.multiple = JSONEditor.AbstractEditor.extend({
register: function() {
if(this.editors) {
for(var i=0; inull';
}
// Array or Object
else if(typeof el === "object") {
// TODO: use theme
var ret = '';
$each(el,function(i,child) {
var html = self.getHTML(child);
// Add the keys to object children
if(!(Array.isArray(el))) {
// TODO: use theme
html = ''+i+': '+html+'
';
}
// TODO: use theme
ret += ''+html+'';
});
if(Array.isArray(el)) ret = ''+ret+'
';
else ret = "';
return ret;
}
// Boolean
else if(typeof el === "boolean") {
return el? 'true' : 'false';
}
// String
else if(typeof el === "string") {
return el.replace(/&/g,'&').replace(//g,'>');
}
// Number
else {
return el;
}
},
setValue: function(val) {
if(this.value !== val) {
this.value = val;
this.refreshValue();
this.onChange();
}
},
destroy: function() {
if(this.display_area && this.display_area.parentNode) this.display_area.parentNode.removeChild(this.display_area);
if(this.title && this.title.parentNode) this.title.parentNode.removeChild(this.title);
if(this.switcher && this.switcher.parentNode) this.switcher.parentNode.removeChild(this.switcher);
this._super();
}
});
JSONEditor.defaults.editors.select = JSONEditor.AbstractEditor.extend({
setValue: function(value,initial) {
value = this.typecast(value||'');
// Sanitize value before setting it
var sanitized = value;
if(this.enum_values.indexOf(sanitized) < 0) {
sanitized = this.enum_values[0];
}
if(this.value === sanitized) {
return;
}
this.input.value = this.enum_options[this.enum_values.indexOf(sanitized)];
if(this.select2) this.select2.select2('val',this.input.value);
this.value = sanitized;
this.onChange();
},
register: function() {
this._super();
if(!this.input) return;
this.input.setAttribute('name',this.formname);
},
unregister: function() {
this._super();
if(!this.input) return;
this.input.removeAttribute('name');
},
getNumColumns: function() {
if(!this.enum_options) return 3;
var longest_text = this.getTitle().length;
for(var i=0; i 2 || (this.enum_options.length && this.enumSource))) {
var options = $extend({},JSONEditor.plugins.select2);
if(this.schema.options && this.schema.options.select2_options) options = $extend(options,this.schema.options.select2_options);
this.select2 = window.jQuery(this.input).select2(options);
var self = this;
this.select2.on('select2-blur',function() {
self.input.value = self.select2.select2('val');
self.onInputChange();
});
}
else {
this.select2 = null;
}
},
postBuild: function() {
this._super();
this.theme.afterInputReady(this.input);
this.setupSelect2();
},
onWatchedFieldChange: function() {
var self = this, vars, j;
// If this editor uses a dynamic select box
if(this.enumSource) {
vars = this.getWatchedFieldValues();
var select_options = [];
var select_titles = [];
for(var i=0; iSize: '+Math.floor((this.value.length-this.value.split(',')[0].length-1)/1.33333)+' bytes';
if(mime.substr(0,5)==="image") {
this.preview.innerHTML += '
';
var img = document.createElement('img');
img.style.maxWidth = '100%';
img.style.maxHeight = '100px';
img.src = this.value;
this.preview.appendChild(img);
}
}
},
enable: function() {
if(this.uploader) this.uploader.disabled = false;
this._super();
},
disable: function() {
if(this.uploader) this.uploader.disabled = true;
this._super();
},
setValue: function(val) {
if(this.value !== val) {
this.value = val;
this.input.value = this.value;
this.refreshPreview();
this.onChange();
}
},
destroy: function() {
if(this.preview && this.preview.parentNode) this.preview.parentNode.removeChild(this.preview);
if(this.title && this.title.parentNode) this.title.parentNode.removeChild(this.title);
if(this.input && this.input.parentNode) this.input.parentNode.removeChild(this.input);
if(this.uploader && this.uploader.parentNode) this.uploader.parentNode.removeChild(this.uploader);
this._super();
}
});
JSONEditor.defaults.editors.upload = JSONEditor.AbstractEditor.extend({
getNumColumns: function() {
return 4;
},
build: function() {
var self = this;
this.title = this.header = this.label = this.theme.getFormInputLabel(this.getTitle());
// Input that holds the base64 string
this.input = this.theme.getFormInputField('hidden');
this.container.appendChild(this.input);
// Don't show uploader if this is readonly
if(!this.schema.readOnly && !this.schema.readonly) {
if(!this.jsoneditor.options.upload) throw "Upload handler required for upload editor";
// File uploader
this.uploader = this.theme.getFormInputField('file');
this.uploader.addEventListener('change',function(e) {
e.preventDefault();
e.stopPropagation();
if(this.files && this.files.length) {
var fr = new FileReader();
fr.onload = function(evt) {
self.preview_value = evt.target.result;
self.refreshPreview();
self.onChange(true);
fr = null;
};
fr.readAsDataURL(this.files[0]);
}
});
}
var description = this.schema.description;
if (!description) description = '';
this.preview = this.theme.getFormInputDescription(description);
this.container.appendChild(this.preview);
this.control = this.theme.getFormControl(this.label, this.uploader||this.input, this.preview);
this.container.appendChild(this.control);
},
refreshPreview: function() {
if(this.last_preview === this.preview_value) return;
this.last_preview = this.preview_value;
this.preview.innerHTML = '';
if(!this.preview_value) return;
var self = this;
var mime = this.preview_value.match(/^data:([^;,]+)[;,]/);
if(mime) mime = mime[1];
if(!mime) mime = 'unknown';
var file = this.uploader.files[0];
this.preview.innerHTML = 'Type: '+mime+', Size: '+file.size+' bytes';
if(mime.substr(0,5)==="image") {
this.preview.innerHTML += '
';
var img = document.createElement('img');
img.style.maxWidth = '100%';
img.style.maxHeight = '100px';
img.src = this.preview_value;
this.preview.appendChild(img);
}
this.preview.innerHTML += '
';
var uploadButton = this.getButton('Upload', 'upload', 'Upload');
this.preview.appendChild(uploadButton);
uploadButton.addEventListener('click',function(event) {
event.preventDefault();
uploadButton.setAttribute("disabled", "disabled");
self.theme.removeInputError(self.uploader);
if (self.theme.getProgressBar) {
self.progressBar = self.theme.getProgressBar();
self.preview.appendChild(self.progressBar);
}
self.jsoneditor.options.upload(self.path, file, {
success: function(url) {
self.setValue(url);
if(self.parent) self.parent.onChildEditorChange(self);
else self.jsoneditor.onChange();
if (self.progressBar) self.preview.removeChild(self.progressBar);
uploadButton.removeAttribute("disabled");
},
failure: function(error) {
self.theme.addInputError(self.uploader, error);
if (self.progressBar) self.preview.removeChild(self.progressBar);
uploadButton.removeAttribute("disabled");
},
updateProgress: function(progress) {
if (self.progressBar) {
if (progress) self.theme.updateProgressBar(self.progressBar, progress);
else self.theme.updateProgressBarUnknown(self.progressBar);
}
}
});
});
},
enable: function() {
if(this.uploader) this.uploader.disabled = false;
this._super();
},
disable: function() {
if(this.uploader) this.uploader.disabled = true;
this._super();
},
setValue: function(val) {
if(this.value !== val) {
this.value = val;
this.input.value = this.value;
this.onChange();
}
},
destroy: function() {
if(this.preview && this.preview.parentNode) this.preview.parentNode.removeChild(this.preview);
if(this.title && this.title.parentNode) this.title.parentNode.removeChild(this.title);
if(this.input && this.input.parentNode) this.input.parentNode.removeChild(this.input);
if(this.uploader && this.uploader.parentNode) this.uploader.parentNode.removeChild(this.uploader);
this._super();
}
});
JSONEditor.defaults.editors.checkbox = JSONEditor.AbstractEditor.extend({
setValue: function(value,initial) {
this.value = !!value;
this.input.checked = this.value;
this.onChange();
},
register: function() {
this._super();
if(!this.input) return;
this.input.setAttribute('name',this.formname);
},
unregister: function() {
this._super();
if(!this.input) return;
this.input.removeAttribute('name');
},
getNumColumns: function() {
return Math.min(12,Math.max(this.getTitle().length/7,2));
},
build: function() {
var self = this;
if(!this.options.compact) {
this.label = this.header = this.theme.getCheckboxLabel(this.getTitle());
}
if(this.schema.description) this.description = this.theme.getFormInputDescription(this.schema.description);
if(this.options.compact) this.container.className += ' compact';
this.input = this.theme.getCheckbox();
this.control = this.theme.getFormControl(this.label, this.input, this.description);
if(this.schema.readOnly || this.schema.readonly) {
this.always_disabled = true;
this.input.disabled = true;
}
this.input.addEventListener('change',function(e) {
e.preventDefault();
e.stopPropagation();
self.value = this.checked;
self.onChange(true);
});
this.container.appendChild(this.control);
},
enable: function() {
if(!this.always_disabled) {
this.input.disabled = false;
}
this._super();
},
disable: function() {
this.input.disabled = true;
this._super();
},
destroy: function() {
if(this.label && this.label.parentNode) this.label.parentNode.removeChild(this.label);
if(this.description && this.description.parentNode) this.description.parentNode.removeChild(this.description);
if(this.input && this.input.parentNode) this.input.parentNode.removeChild(this.input);
this._super();
}
});
var matchKey = (function () {
var elem = document.documentElement;
if (elem.matches) return 'matches';
else if (elem.webkitMatchesSelector) return 'webkitMatchesSelector';
else if (elem.mozMatchesSelector) return 'mozMatchesSelector';
else if (elem.msMatchesSelector) return 'msMatchesSelector';
else if (elem.oMatchesSelector) return 'oMatchesSelector';
})();
JSONEditor.AbstractTheme = Class.extend({
getContainer: function() {
return document.createElement('div');
},
getFloatRightLinkHolder: function() {
var el = document.createElement('div');
el.style = el.style || {};
el.style.cssFloat = 'right';
el.style.marginLeft = '10px';
return el;
},
getModal: function() {
var el = document.createElement('div');
el.style.backgroundColor = 'white';
el.style.border = '1px solid black';
el.style.boxShadow = '3px 3px black';
el.style.position = 'absolute';
el.style.zIndex = '10';
el.style.display = 'none';
return el;
},
getGridContainer: function() {
var el = document.createElement('div');
return el;
},
getGridRow: function() {
var el = document.createElement('div');
el.className = 'row';
return el;
},
getGridColumn: function() {
var el = document.createElement('div');
return el;
},
setGridColumnSize: function(el,size) {
},
getLink: function(text) {
var el = document.createElement('a');
el.setAttribute('href','#');
el.appendChild(document.createTextNode(text));
return el;
},
disableHeader: function(header) {
header.style.color = '#ccc';
},
disableLabel: function(label) {
label.style.color = '#ccc';
},
enableHeader: function(header) {
header.style.color = '';
},
enableLabel: function(label) {
label.style.color = '';
},
getFormInputLabel: function(text) {
var el = document.createElement('label');
el.appendChild(document.createTextNode(text));
return el;
},
getCheckboxLabel: function(text) {
var el = this.getFormInputLabel(text);
el.style.fontWeight = 'normal';
return el;
},
getHeader: function(text) {
var el = document.createElement('h5');
if(typeof text === "string") {
el.textContent = text;
}
else {
el.appendChild(text);
}
return el;
},
getCheckbox: function() {
var el = this.getFormInputField('checkbox');
el.style.display = 'inline-block';
el.style.width = 'auto';
return el;
},
getMultiCheckboxHolder: 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;
},
getSelectInput: function(options) {
var select = document.createElement('select');
if(options) this.setSelectOptions(select, options);
return select;
},
getSwitcher: function(options) {
var switcher = this.getSelectInput(options);
switcher.style.backgroundColor = 'transparent';
switcher.style.display = 'inline-block';
switcher.style.fontStyle = 'italic';
switcher.style.fontWeight = 'normal';
switcher.style.height = 'auto';
switcher.style.marginBottom = 0;
switcher.style.marginLeft = '5px';
switcher.style.padding = '0 0 0 3px';
switcher.style.width = 'auto';
return switcher;
},
getSwitcherOptions: function(switcher) {
return switcher.getElementsByTagName('option');
},
setSwitcherOptions: function(switcher, options, titles) {
this.setSelectOptions(switcher, options, titles);
},
setSelectOptions: function(select, options, titles) {
titles = titles || [];
select.innerHTML = '';
for(var i=0; i');
input.errmsg = input.parentNode.getElementsByClassName('error')[0];
}
else {
input.errmsg.style.display = '';
}
input.errmsg.textContent = text;
},
removeInputError: function(input) {
if(!input.errmsg) return;
input.group.className = input.group.className.replace(/ error/g,'');
input.errmsg.style.display = 'none';
},
getProgressBar: function() {
var progressBar = document.createElement('div');
progressBar.className = 'progress';
var meter = document.createElement('span');
meter.className = 'meter';
meter.style.width = '0%';
progressBar.appendChild(meter);
return progressBar;
},
updateProgressBar: function(progressBar, progress) {
if (!progressBar) return;
progressBar.firstChild.style.width = progress + '%';
},
updateProgressBarUnknown: function(progressBar) {
if (!progressBar) return;
progressBar.firstChild.style.width = '100%';
}
});
// Foundation 3 Specific Theme
JSONEditor.defaults.themes.foundation3 = JSONEditor.defaults.themes.foundation.extend({
getHeaderButtonHolder: function() {
var el = this._super();
el.style.fontSize = '.6em';
return el;
},
getFormInputLabel: function(text) {
var el = this._super(text);
el.style.fontWeight = 'bold';
return el;
},
getTabHolder: function() {
var el = document.createElement('div');
el.className = 'row';
el.innerHTML = "
";
return el;
},
setGridColumnSize: function(el,size) {
var sizes = ['zero','one','two','three','four','five','six','seven','eight','nine','ten','eleven','twelve'];
el.className = 'columns '+sizes[size];
},
getTab: function(text) {
var el = document.createElement('dd');
var a = document.createElement('a');
a.setAttribute('href','#');
a.appendChild(text);
el.appendChild(a);
return el;
},
getTabContentHolder: function(tab_holder) {
return tab_holder.children[1];
},
getTabContent: function() {
var el = document.createElement('div');
el.className = 'content active';
el.style.paddingLeft = '5px';
return el;
},
markTabActive: function(tab) {
tab.className += ' active';
},
markTabInactive: function(tab) {
tab.className = tab.className.replace(/\s*active/g,'');
},
addTab: function(holder, tab) {
holder.children[0].appendChild(tab);
}
});
// Foundation 4 Specific Theme
JSONEditor.defaults.themes.foundation4 = JSONEditor.defaults.themes.foundation.extend({
getHeaderButtonHolder: function() {
var el = this._super();
el.style.fontSize = '.6em';
return el;
},
setGridColumnSize: function(el,size) {
el.className = 'columns large-'+size;
},
getFormInputDescription: function(text) {
var el = this._super(text);
el.style.fontSize = '.8rem';
return el;
},
getFormInputLabel: function(text) {
var el = this._super(text);
el.style.fontWeight = 'bold';
return el;
}
});
// Foundation 5 Specific Theme
JSONEditor.defaults.themes.foundation5 = JSONEditor.defaults.themes.foundation.extend({
getFormInputDescription: function(text) {
var el = this._super(text);
el.style.fontSize = '.8rem';
return el;
},
setGridColumnSize: function(el,size) {
el.className = 'columns medium-'+size;
},
getButton: function(text, icon, title) {
var el = this._super(text,icon,title);
el.className = el.className.replace(/\s*small/g,'') + ' tiny';
return el;
},
getTabHolder: function() {
var el = document.createElement('div');
el.innerHTML = "
";
return el;
},
getTab: function(text) {
var el = document.createElement('dd');
var a = document.createElement('a');
a.setAttribute('href','#');
a.appendChild(text);
el.appendChild(a);
return el;
},
getTabContentHolder: function(tab_holder) {
return tab_holder.children[1];
},
getTabContent: function() {
var el = document.createElement('div');
el.className = 'content active';
el.style.paddingLeft = '5px';
return el;
},
markTabActive: function(tab) {
tab.className += ' active';
},
markTabInactive: function(tab) {
tab.className = tab.className.replace(/\s*active/g,'');
},
addTab: function(holder, tab) {
holder.children[0].appendChild(tab);
}
});
JSONEditor.defaults.themes.html = JSONEditor.AbstractTheme.extend({
getFormInputLabel: function(text) {
var el = this._super(text);
el.style.display = 'block';
el.style.marginBottom = '3px';
el.style.fontWeight = 'bold';
return el;
},
getFormInputDescription: function(text) {
var el = this._super(text);
el.style.fontSize = '.8em';
el.style.margin = 0;
el.style.display = 'inline-block';
el.style.fontStyle = 'italic';
return el;
},
getIndentedPanel: function() {
var el = this._super();
el.style.border = '1px solid #ddd';
el.style.padding = '5px';
el.style.margin = '5px';
el.style.borderRadius = '3px';
return el;
},
getChildEditorHolder: function() {
var el = this._super();
el.style.marginBottom = '8px';
return el;
},
getHeaderButtonHolder: function() {
var el = this.getButtonHolder();
el.style.display = 'inline-block';
el.style.marginLeft = '10px';
el.style.fontSize = '.8em';
el.style.verticalAlign = 'middle';
return el;
},
getTable: function() {
var el = this._super();
el.style.borderBottom = '1px solid #ccc';
el.style.marginBottom = '5px';
return el;
},
addInputError: function(input, text) {
input.style.borderColor = 'red';
if(!input.errmsg) {
var group = this.closest(input,'.form-control');
input.errmsg = document.createElement('div');
input.errmsg.setAttribute('class','errmsg');
input.errmsg.style = input.errmsg.style || {};
input.errmsg.style.color = 'red';
group.appendChild(input.errmsg);
}
else {
input.errmsg.style.display = 'block';
}
input.errmsg.innerHTML = '';
input.errmsg.appendChild(document.createTextNode(text));
},
removeInputError: function(input) {
input.style.borderColor = '';
if(input.errmsg) input.errmsg.style.display = 'none';
},
getProgressBar: function() {
var max = 100, start = 0;
var progressBar = document.createElement('progress');
progressBar.setAttribute('max', max);
progressBar.setAttribute('value', start);
return progressBar;
},
updateProgressBar: function(progressBar, progress) {
if (!progressBar) return;
progressBar.setAttribute('value', progress);
},
updateProgressBarUnknown: function(progressBar) {
if (!progressBar) return;
progressBar.removeAttribute('value');
}
});
JSONEditor.defaults.themes.jqueryui = JSONEditor.AbstractTheme.extend({
getTable: function() {
var el = this._super();
el.setAttribute('cellpadding',5);
el.setAttribute('cellspacing',0);
return el;
},
getTableHeaderCell: function(text) {
var el = this._super(text);
el.className = 'ui-state-active';
el.style.fontWeight = 'bold';
return el;
},
getTableCell: function() {
var el = this._super();
el.className = 'ui-widget-content';
return el;
},
getHeaderButtonHolder: function() {
var el = this.getButtonHolder();
el.style.marginLeft = '10px';
el.style.fontSize = '.6em';
el.style.display = 'inline-block';
return el;
},
getFormInputDescription: function(text) {
var el = this.getDescription(text);
el.style.marginLeft = '10px';
el.style.display = 'inline-block';
return el;
},
getFormControl: function(label, input, description) {
var el = this._super(label,input,description);
if(input.type === 'checkbox') {
el.style.lineHeight = '25px';
el.style.padding = '3px 0';
}
else {
el.style.padding = '4px 0 8px 0';
}
return el;
},
getDescription: function(text) {
var el = document.createElement('span');
el.style.fontSize = '.8em';
el.style.fontStyle = 'italic';
el.textContent = text;
return el;
},
getButtonHolder: function() {
var el = document.createElement('div');
el.className = 'ui-buttonset';
el.style.fontSize = '.7em';
return el;
},
getFormInputLabel: function(text) {
var el = document.createElement('label');
el.style.fontWeight = 'bold';
el.style.display = 'block';
el.textContent = text;
return el;
},
getButton: function(text, icon, title) {
var button = document.createElement("button");
button.className = 'ui-button ui-widget ui-state-default ui-corner-all';
// Icon only
if(icon && !text) {
button.className += ' ui-button-icon-only';
icon.className += ' ui-button-icon-primary ui-icon-primary';
button.appendChild(icon);
}
// Icon and Text
else if(icon) {
button.className += ' ui-button-text-icon-primary';
icon.className += ' ui-button-icon-primary ui-icon-primary';
button.appendChild(icon);
}
// Text only
else {
button.className += ' ui-button-text-only';
}
var el = document.createElement('span');
el.className = 'ui-button-text';
el.textContent = text||title||".";
button.appendChild(el);
button.setAttribute('title',title);
return button;
},
setButtonText: function(button,text, icon, title) {
button.innerHTML = '';
button.className = 'ui-button ui-widget ui-state-default ui-corner-all';
// Icon only
if(icon && !text) {
button.className += ' ui-button-icon-only';
icon.className += ' ui-button-icon-primary ui-icon-primary';
button.appendChild(icon);
}
// Icon and Text
else if(icon) {
button.className += ' ui-button-text-icon-primary';
icon.className += ' ui-button-icon-primary ui-icon-primary';
button.appendChild(icon);
}
// Text only
else {
button.className += ' ui-button-text-only';
}
var el = document.createElement('span');
el.className = 'ui-button-text';
el.textContent = text||title||".";
button.appendChild(el);
button.setAttribute('title',title);
},
getIndentedPanel: function() {
var el = document.createElement('div');
el.className = 'ui-widget-content ui-corner-all';
el.style.padding = '1em 1.4em';
el.style.marginBottom = '20px';
return el;
},
afterInputReady: function(input) {
if(input.controls) return;
input.controls = this.closest(input,'.form-control');
},
addInputError: function(input,text) {
if(!input.controls) return;
if(!input.errmsg) {
input.errmsg = document.createElement('div');
input.errmsg.className = 'ui-state-error';
input.controls.appendChild(input.errmsg);
}
else {
input.errmsg.style.display = '';
}
input.errmsg.textContent = text;
},
removeInputError: function(input) {
if(!input.errmsg) return;
input.errmsg.style.display = 'none';
},
markTabActive: function(tab) {
tab.className = tab.className.replace(/\s*ui-widget-header/g,'')+' ui-state-active';
},
markTabInactive: function(tab) {
tab.className = tab.className.replace(/\s*ui-state-active/g,'')+' ui-widget-header';
}
});
JSONEditor.AbstractIconLib = Class.extend({
mapping: {
collapse: '',
expand: '',
"delete": '',
edit: '',
add: '',
cancel: '',
save: '',
moveup: '',
movedown: ''
},
icon_prefix: '',
getIconClass: function(key) {
if(this.mapping[key]) return this.icon_prefix+this.mapping[key];
else return null;
},
getIcon: function(key) {
var iconclass = this.getIconClass(key);
if(!iconclass) return null;
var i = document.createElement('i');
i.className = iconclass;
return i;
}
});
JSONEditor.defaults.iconlibs.bootstrap2 = JSONEditor.AbstractIconLib.extend({
mapping: {
collapse: 'chevron-down',
expand: 'chevron-up',
"delete": 'trash',
edit: 'pencil',
add: 'plus',
cancel: 'ban-circle',
save: 'ok',
moveup: 'arrow-up',
movedown: 'arrow-down'
},
icon_prefix: 'icon-'
});
JSONEditor.defaults.iconlibs.bootstrap3 = JSONEditor.AbstractIconLib.extend({
mapping: {
collapse: 'chevron-down',
expand: 'chevron-right',
"delete": 'remove',
edit: 'pencil',
add: 'plus',
cancel: 'floppy-remove',
save: 'floppy-saved',
moveup: 'arrow-up',
movedown: 'arrow-down'
},
icon_prefix: 'glyphicon glyphicon-'
});
JSONEditor.defaults.iconlibs.fontawesome3 = JSONEditor.AbstractIconLib.extend({
mapping: {
collapse: 'chevron-down',
expand: 'chevron-right',
"delete": 'remove',
edit: 'pencil',
add: 'plus',
cancel: 'ban-circle',
save: 'save',
moveup: 'arrow-up',
movedown: 'arrow-down'
},
icon_prefix: 'icon-'
});
JSONEditor.defaults.iconlibs.fontawesome4 = JSONEditor.AbstractIconLib.extend({
mapping: {
collapse: 'caret-square-o-down',
expand: 'caret-square-o-right',
"delete": 'times',
edit: 'pencil',
add: 'plus',
cancel: 'ban',
save: 'save',
moveup: 'arrow-up',
movedown: 'arrow-down'
},
icon_prefix: 'fa fa-'
});
JSONEditor.defaults.iconlibs.foundation2 = JSONEditor.AbstractIconLib.extend({
mapping: {
collapse: 'minus',
expand: 'plus',
"delete": 'remove',
edit: 'edit',
add: 'add-doc',
cancel: 'error',
save: 'checkmark',
moveup: 'up-arrow',
movedown: 'down-arrow'
},
icon_prefix: 'foundicon-'
});
JSONEditor.defaults.iconlibs.foundation3 = JSONEditor.AbstractIconLib.extend({
mapping: {
collapse: 'minus',
expand: 'plus',
"delete": 'x',
edit: 'pencil',
add: 'page-add',
cancel: 'x-circle',
save: 'save',
moveup: 'arrow-up',
movedown: 'arrow-down'
},
icon_prefix: 'fi-'
});
JSONEditor.defaults.iconlibs.jqueryui = JSONEditor.AbstractIconLib.extend({
mapping: {
collapse: 'triangle-1-s',
expand: 'triangle-1-e',
"delete": 'trash',
edit: 'pencil',
add: 'plusthick',
cancel: 'closethick',
save: 'disk',
moveup: 'arrowthick-1-n',
movedown: 'arrowthick-1-s'
},
icon_prefix: 'ui-icon ui-icon-'
});
JSONEditor.defaults.templates["default"] = function() {
return {
compile: function(template) {
var matches = template.match(/{{\s*([a-zA-Z0-9\-_ \.]+)\s*}}/g);
var l = matches && matches.length;
// Shortcut if the template contains no variables
if(!l) return function() { return template; };
// Pre-compute the search/replace functions
// This drastically speeds up template execution
var replacements = [];
var get_replacement = function(i) {
var p = matches[i].replace(/[{}]+/g,'').trim().split('.');
var n = p.length;
var func;
if(n > 1) {
var cur;
func = function(vars) {
cur = vars;
for(i=0; i= 0) {
return 'multiselect';
}
});
// Use the multiple editor for schemas with `oneOf` set
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.
*/
(function() {
if(window.jQuery || window.Zepto) {
var $ = window.jQuery || window.Zepto;
$.jsoneditor = JSONEditor.defaults;
$.fn.jsoneditor = function(options) {
var self = this;
var editor = this.data('jsoneditor');
if(options === 'value') {
if(!editor) throw "Must initialize jsoneditor before getting/setting the value";
// Set value
if(arguments.length > 1) {
editor.setValue(arguments[1]);
}
// Get value
else {
return editor.getValue();
}
}
else if(options === 'validate') {
if(!editor) throw "Must initialize jsoneditor before validating";
// Validate a specific value
if(arguments.length > 1) {
return editor.validate(arguments[1]);
}
// Validate current value
else {
return editor.validate();
}
}
else if(options === 'destroy') {
if(editor) {
editor.destroy();
this.data('jsoneditor',null);
}
}
else {
// Destroy first
if(editor) {
editor.destroy();
}
// Create editor
editor = new JSONEditor(this.get(0),options);
this.data('jsoneditor',editor);
// Setup event listeners
editor.on('change',function() {
self.trigger('change');
});
editor.on('ready',function() {
self.trigger('ready');
});
}
return this;
};
}
})();
window.JSONEditor = JSONEditor;
})();
//# sourceMappingURL=jsoneditor.js.map