Created
November 4, 2014 23:15
-
-
Save AubreyHewes/780b09c3bb6553b4d02a to your computer and use it in GitHub Desktop.
JSONEditor Theme: Bootstrap3 (form-horizonta)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*jshint strict: false, -W116: false, -W098: false */ | |
/** | |
* Copy of the Bootstrap 3 Theme; tweaked for horizontal form (form-horizontal) | |
* | |
* @todo remove ridiculous amount of nesting; is a lib issue; create issue? | |
*/ | |
JSONEditor.defaults.themes.bootstrap3horizontal = JSONEditor.AbstractTheme.extend({ | |
labelWidth: 3, | |
inputWidth: 9, | |
/** | |
* Add a constructor to create/override other JSONEditor classes | |
*/ | |
init: function () { | |
/** | |
* Bootstrap 3 horizontal compatible multiple (tested on "oneOf") editor; remove proprietary fixed dom/styling (field within a form-group; styled as other fields) | |
* | |
* Unfortunately we have to overload core and copy a load of the overloaded core to get this to be compatible.. | |
* | |
* @todo create lib issue | |
*/ | |
JSONEditor.defaults.editors.multiple = JSONEditor.defaults.editors.multiple.extend({ | |
build: function () { | |
var self = this; | |
var container = this.container; | |
this.header = this.label = this.theme.getFormInputLabel(this.getTitle()); | |
this.switcher = this.theme.getSelectInput(this.display_text); | |
container.appendChild(this.theme.getFormControl(this.label, this.switcher, this.display_text.join(', '))); | |
this.switcher.addEventListener('change',function(e) { | |
e.preventDefault(); | |
e.stopPropagation(); | |
self.switchEditor(self.display_text.indexOf(this.value)); | |
self.onChange(true); | |
}); | |
this.editor_holder = document.createElement('div'); | |
container.appendChild(this.editor_holder); | |
this.switcher_options = this.theme.getSwitcherOptions(this.switcher); | |
$.each(this.types,function(i,type) { | |
self.editors[i] = false; | |
var schema; | |
if(typeof type === "string") { | |
schema = $.extend({},self.schema); | |
schema.type = type; | |
} | |
else { | |
schema = $.extend({},self.schema,type); | |
// If we need to merge `required` arrays | |
if(type.required && Array.isArray(type.required) && self.schema.required && Array.isArray(self.schema.required)) { | |
schema.required = self.schema.required.concat(type.required); | |
} | |
} | |
self.validators[i] = new JSONEditor.Validator(self.jsoneditor,schema); | |
}); | |
this.switchEditor(0); | |
} | |
}); | |
// add label "for" attribute and input "id" .. making labels clickable @note is known lib issue | |
$.each(JSONEditor.defaults.editors, function (name, editor) { | |
if (name === 'options') return; // "options" is not an editor but the global editor options | |
JSONEditor.defaults.editors[name] = editor.extend({ | |
register: function () { | |
this._super(); | |
// superfluous prefix (but removes any possible id conflicts) | |
var elId = 'jsoneditor-' + this.formname.replace(/([^\[]+)\[(.+)\]/, '$1-$2').replace(/\]\[/gim, '-'); | |
if (this.input) this.input.setAttribute('id', elId); | |
if (this.switcher) this.switcher.setAttribute('id', elId); | |
if (this.label) this.label.setAttribute('for', elId); | |
} | |
}); | |
}); | |
}, | |
getSwitcher: function(options) { | |
var switcher = this.getSelectInput(options); | |
return switcher; | |
}, | |
getChildEditorHolder: function() { // removes hardcoded styling | |
var el = document.createElement('div'); | |
return el; | |
}, | |
getGridRow: function() { // removes hardcoded styling; still a superfluous nest | |
var el = document.createElement('div'); | |
return el; | |
}, | |
getSelectInput: function(options) { | |
var el = this._super(options); | |
el.className += 'form-control'; | |
return el; | |
}, | |
setGridColumnSize: function(el,size) { // not using grid; so there | |
//el.className = 'col-md-'+size; | |
}, | |
afterInputReady: function(input) { | |
if(input.controlgroup) return; | |
input.controlgroup = this.closest(input,'.form-group'); | |
if(this.closest(input,'.compact')) { | |
input.controlgroup.style.marginBottom = 0; | |
} | |
// TODO: use bootstrap slider | |
}, | |
getTextareaInput: function() { | |
var el = document.createElement('textarea'); | |
el.className = 'form-control'; | |
return el; | |
}, | |
getRangeInput: function(min, max, step) { | |
// TODO: use better slider | |
return this._super(min, max, step); | |
}, | |
getFormInputField: function(type) { | |
var el = this._super(type); | |
if(type !== 'checkbox') { | |
el.className += 'form-control'; | |
} | |
return el; | |
}, | |
getFormControl: function(label, input, description) { | |
var group = document.createElement('div'); | |
if(label && input.type === 'checkbox') { // not yet used - just removed hardcoded styles | |
group.className += ' checkbox'; | |
label.appendChild(input); | |
//label.style.fontSize = '14px'; | |
//group.style.marginTop = '0'; | |
group.appendChild(label); | |
//input.style.position = 'relative'; | |
//input.style.cssFloat = 'left'; | |
if(description) group.appendChild(description); | |
} | |
else { | |
group.className += ' form-group'; | |
if(label) { | |
label.className += ' col-xs-' + this.labelWidth + ' control-label'; | |
label.for = ""; | |
group.appendChild(label); | |
} | |
var container = document.createElement('div'); | |
container.className += ' col-xs-' + this.inputWidth; | |
input.placeholder = description; | |
// set title for bootstrap tooltips | |
if (label && label.innerText) { | |
input.title = label.innerText += ': ' + description + ''; | |
} else { | |
input.title = description; | |
} | |
container.appendChild(input); | |
group.appendChild(container); | |
} | |
return group; | |
}, | |
getIndentedPanel: function() { // wells are ugly within a form; breaks the horizontal form; is superfluous nesting | |
var el = document.createElement('div'); | |
//el.className = 'well well-sm'; | |
return el; | |
}, | |
getFormInputDescription: function(text) { // description is used as the placeholder/title/info | |
//var el = document.createElement('p'); | |
//el.className = 'help-block'; | |
//el.textContent = text; | |
//return el; | |
return text; | |
}, | |
getHeaderButtonHolder: function() { // removed the hard styling - our json-editor-bootstrap removes all buttons after json-editor render; something the library should maybe do? otherwise pressing enter activates collapsing the object.. | |
var el = this.getButtonHolder(); | |
//el.style.marginLeft = '10px'; | |
return el; | |
}, | |
getButtonHolder: function() { // not yet used (so no idea) | |
var el = document.createElement('div'); | |
el.className = 'btn-group'; | |
return el; | |
}, | |
getButton: function(text, icon, title) { // not yet used (so no idea) | |
var el = this._super(text, icon, title); | |
el.className += 'btn btn-default'; | |
return el; | |
}, | |
getTable: function() { // not yet used (so no idea) - just removed the hard styling | |
var el = document.createElement('table'); | |
el.className = 'table table-bordered'; | |
//el.style.width = 'auto'; | |
//el.style.maxWidth = 'none'; | |
return el; | |
}, | |
addInputError: function(input,text) { | |
if(!input.controlgroup) return; | |
if (input.controlgroup.className.indexOf(' has-error') === -1) { | |
input.controlgroup.className += ' has-error'; | |
} | |
if(!input.errmsg) { | |
input.errmsg = document.createElement('p'); | |
input.errmsg.className = 'help-block errormsg ' + | |
'col-xs-offset-' + this.labelWidth + ' col-xs-' + this.inputWidth; // error is now below the field | |
input.controlgroup.appendChild(input.errmsg); | |
} | |
else { | |
input.errmsg.style.display = ''; | |
} | |
input.errmsg.textContent = text; | |
}, | |
removeInputError: function(input) { | |
if(!input.errmsg) return; | |
input.errmsg.style.display = 'none'; | |
input.controlgroup.className = input.controlgroup.className.replace(/\s?has-error/g,''); | |
}, | |
getTabHolder: function() { // not yet used (so no idea) | |
var el = document.createElement('div'); | |
el.innerHTML = "<div class='tabs list-group col-md-2'></div><div class='col-md-10'></div>"; | |
el.className = 'rows'; | |
return el; | |
}, | |
getTab: function(text) { // not yet used (so no idea) | |
var el = document.createElement('a'); | |
el.className = 'list-group-item'; | |
el.setAttribute('href','#'); | |
el.appendChild(text); | |
return el; | |
}, | |
markTabActive: function(tab) { // not yet used (so no idea) | |
tab.className += ' active'; | |
}, | |
markTabInactive: function(tab) { // not yet used (so no idea) | |
tab.className = tab.className.replace(/\s?active/g,''); | |
}, | |
getProgressBar: function() { // not yet used (so no idea) | |
var min = 0, max = 100, start = 0; | |
var container = document.createElement('div'); | |
container.className = 'progress'; | |
var bar = document.createElement('div'); | |
bar.className = 'progress-bar'; | |
bar.setAttribute('role', 'progressbar'); | |
bar.setAttribute('aria-valuenow', start); | |
bar.setAttribute('aria-valuemin', min); | |
bar.setAttribute('aria-valuenax', max); | |
bar.innerHTML = start + "%"; | |
container.appendChild(bar); | |
return container; | |
}, | |
updateProgressBar: function(progressBar, progress) { // not yet used (so no idea) | |
if (!progressBar) return; | |
var bar = progressBar.firstChild; | |
var percentage = progress + "%"; | |
bar.setAttribute('aria-valuenow', progress); | |
bar.style.width = percentage; | |
bar.innerHTML = percentage; | |
}, | |
updateProgressBarUnknown: function(progressBar) { // not yet used (so no idea) | |
if (!progressBar) return; | |
var bar = progressBar.firstChild; | |
progressBar.className = 'progress progress-striped active'; | |
bar.removeAttribute('aria-valuenow'); | |
bar.style.width = '100%'; | |
bar.innerHTML = ''; | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment