UNPKG

json-object-editor

Version:

JOE the Json Object Editor | Platform Edition

1,278 lines (1,151 loc) 558 kB
/* -------------------------------------------------------- * * JOE - v1.5.0 * Created by: Corey Hadden * * -------------------------------------------------------- */ /*/--------------------------------------------------------- Craydent LLC Copyright 2014 (http://craydent.com/joe) Dual licensed under the MIT or GPL Version 2 licenses. (http://craydent.com/license) ---------------------------------------------------------/*/ //render field - self.renderObjectPropFieldUI //render list item - self.renderListItems() //single field list item -renderFieldListItem() if($c.isMobile()){ document.getElementsByTagName('html')[0].className +=' touch'; }else{ document.getElementsByTagName('html')[0].className +=' no-touch'; } window._joeEditingHash = false; var _webworkers = false; var _joeworker; if (!!window.Worker) { _webworkers = true } var joe_web_dir = '//' + location.hostname + ':' + (location.port||((location.protocol=="https:")?443:80)) + "/JsonObjectEditor/"; if(location && location.origin == 'file://'){ joe_web_dir = location.href.slice(0,location.href.lastIndexOf('/')+1); } __docWriter =function(src,type,cancelWrite){ var type=type || 'js'; var html = ''; switch(type.toLowerCase()){ case 'js': case 'javascript': html +='<script type="text/javascript" src="'+src+'"></script>'; break; case 'css': case 'stylesheet': html +='<link href="'+src+'" rel="stylesheet" type="text/css">'; break; } if(!cancelWrite){ document.write(html); } return html; }; __loadAdditionalFiles = function(){ var bonuses =''; if (typeof jQuery == 'undefined') { //console.log('loading jquery'); /* bonuses+= __docWriter(joe_web_dir+"js/libs/jquery-1.11.3.min.js",'js')+ __docWriter(joe_web_dir+"js/libs/jquery-ui.min.js");*/ __docWriter(joe_web_dir+"js/libs/jquery-1.11.3.min.js",'js')+ __docWriter(joe_web_dir+"js/libs/jquery-ui.min.js"); } bonuses += __docWriter(joe_web_dir+"js/libs/jquery.ui.touch-punch.min.js"); if (typeof Craydent == 'undefined' || (!Craydent.VERSION || Craydent.VERSION < '1.7.37')) { bonuses+= __docWriter(joe_web_dir+"js/libs/craydent-1.8.1.js",'js',true); } /* bonuses+= __docWriter(joe_web_dir+'css/joe.css','css','css',true) +__docWriter(joe_web_dir+'js/ace/ace.js','js',true) +__docWriter(joe_web_dir+'js/plugins/tinymce.min.js','js',true); */ document.write(bonuses); }; function __require(file,callback){ var head=document.getElementsByTagName("head")[0]; var script=document.createElement('script'); script.src=file; script.type='text/javascript'; //real browsers script.onload=callback; //Internet explorer script.onreadystatechange = function() { if (this.readyState == 'complete') { callback(); } } head.appendChild(script); } /*var __joeFieldTypes = [ 'text', 'select', 'code', 'rendering', 'date', 'boolean', 'geo', 'image', 'url', 'objectList', 'objectReference', 'group', 'content' ];*/ //__loadAdditionalFiles(); function JsonObjectEditor(specs){ var self = this; self.initialDocumentTitle = document.title; $c.TEMPLATE_VARS.push( {variable:'/textarea',value:'</textarea>'}, {variable:'textarea',value:'<textarea>'}, {variable:'SERVER',value:'//'+$c.SERVER} ); initialized = false; var colCount = 1; var listMode = false; var gridMode = false; var tableMode = false,tableSpecs; var multiEdit = false; this.VERSION = '1.0.1'; window._joes = window._joes || []; this.joe_index = window._joes.length; if(!window._joes.length){window._joe = this;} this.Error = { log:[], add:function(message,error,data){ var payload = { caller: arguments.callee.caller, callerargs: arguments.callee.caller.arguments, message:message, error:error, stack:new Error(error).stack, data:data, timestamp:(new Date()).toISOString(), _id:cuid() }; self.Error.log.push(payload); logit('[error]: '+message); }, show:function(){ self.show(self.Error.log,{schema:{ title:'${message}', idprop:'_id', listView:{ title: '<joe-title>${message}</joe-title><joe-subtitle>${timestamp}</joe-subtitle>', listWindowTitle: 'Errors' }, fields:[ 'error:code', 'message', 'stack:code', {name:'data',type:'content',run:function(data,obj){ return '<div><pre>'+tryEval(data)+'</pre></div>'; }}, 'callerargs:code', 'timestamp:guid', '_id' ] }}); } }; window._joes.push(this); this.Cache = { static:{}, list:[], lookup:{}, clear:function(){ self.Cache.lookup = {}; self.Cache.list = []; }, remove:function(id){ //self.cache. }, get:function(id,specs){ var cacheitem = self.Cache.lookup[id]; if(cacheitem && typeof cacheitem.value == "function" && cacheitem.type =="callback"){ return cacheitem.value(cacheitem.data,cacheitem.id); } if(!cacheitem){ //if(autoadd){ var obj = self.search(id)[0]||false; if(obj){ self.Cache.add(obj,{id:id}) return obj; } //} return false; } return cacheitem.value; }, callback:function(id){ var cacheitem = self.Cache.lookup[id]; if(typeof cacheitem.value == "function"){ return cacheitem.value(cacheitem.data,cacheitem.id); } else {logit('cache item is not a function');} }, add:function(value,specs){ var obj = $.extend({ id:cuid(), value:value, parent:self.joe_index },specs); self.Cache.list.push(obj.id); self.Cache.lookup[obj.id] =obj; return obj; } }; this.Cache.set = this.Cache.add; this.history = []; /*--------------------------------------------------------------------> 0 | CONFIG <--------------------------------------------------------------------*/ var defaults = { localStorage:false, container:'body', joeprofile:{ lockedFields:['joeUpdated'], hiddenFields:[] }, profiles:{}, fields:{}, schemas:{ 'rendering': { title:'HTML Rendering', callback:function(){alert('yo');} //fields:['id','name','thingType','legs','species','weight','color','gender'], //_listID:'id', //_listTitle:'${name} ${species}' }}, compact:false, useControlEnter:true, useEscapeKey:false, autoInit:false, dynamicDisplay:($(window).height() < 800 && $c.isMobile())?12:20, sans:false, listSubMenu:true, documentTitle:false,//tmplate to set document title useInset:true, speechRecognition:false }; this.specs = $.extend({},defaults,specs||{}); if(this.specs.localStorage && typeof(Storage) === "undefined"){ alert('no local storage'); this.specs.LocalStorage = false; } this.Data = {}; this.Render = {}; //TODO: make current.clear a function //TODO: check for class/id selector this.container = $(this.specs.container); this.fields = this.specs.fields; this.Fields = { reset:function(propname){ var field = self.Fields.get(propname); self.current.object[propname] = field.reset; self.Fields.rerender(propname); } }; //configure schemas this.schemas = this.specs.schemas; /* this.schemas._function = { idprop:'name' };*/ for(var s in _joe.schemas){ _joe.schemas[s].__schemaname = _joe.schemas[s].name = s; _joe.schemas[s]._id = cuid(); } this.current = {}; //filters:{}, this.current.clear= function(){ /*|{ featured:true, description:'cleans up variables that currently exist between a single JOE showings.', tags:'cleanup, reset', category:'core' }|*/ self.current.list = null; self.current.subsets = null; self.current.subset = null; self.current.filters = {}; self.current.fields = []; self.current.schema = null; self.current.object = null; self.current.reset = {}; self.current.cache = {}; self.current.title = null; self.current.keyword = ''; if(_joes.length == 1){ document.title = self.initialDocumentTitle; } }; //profile this.defaultProfile = this.specs.defaultProfile || this.specs.joeprofile; this.current.profile = this.defaultProfile; this.ace_editors = {}; this.Render.stripeColor=function(opt,colorfunc){ var color = self.propAsFuncOrValue((colorfunc||opt.stripecolor),opt,null,_jco()); var title = ''; if(color && $c.isObject(color)){ title = ' title="'+color.title+'" '; color = color.color; } var h = '<joe-stripe-color '+title+(color && 'style="background-color:'+color+';"' || '')+'></joe-stripe-color>'; return h; }; this.Render.bgColor = function(opt,colorfunc){ var color = self.propAsFuncOrValue((colorfunc||opt.bgcolor),opt,null,_jco()); if(color && $c.isObject(color)){ color = color.color; } var h = '<joe-bg-color '+(color && 'style="background-color:'+color+';"' || '')+'></joe-bg-color>'; return h; }; /*--------------------------------------------------------------------> 1 | INIT <--------------------------------------------------------------------*/ this.init = function(callback) { /*|{ featured:true, description:'primary entry point into JOE, sets up the UI necessary', tags:'init, framework', category:'core' }|*/ if(initialized){return false;} beginLogGroup('JOE init'); self.current.clear(); var html = self.renderFramework( self.renderEditorHeader() + self.renderEditorContent() + self.renderEditorFooter() ); self.container.append(html); self.overlay = $('.joe-overlay[data-joeindex=' + self.joe_index + ']'); self.panel = self.overlay.find('.joe-overlay-panel'); self.initKeyHandlers(); self.Speech.init(); self.readHashLink(); /* $(window).on('hashChange',function(h,i,c){ logit(h,i,c); });*/ window.addEventListener("hashchange", function(newH,oldH){ var useHash = $GET('!') || location.hash; if (!useHash || self.joe_index != 0 || !specs.useHashlink) { return false; } //logit(newH); if(!window._joeEditingHash){ self.readHashLink(); //logit(useHash); } }, false); var respond_timeout; //self.respond(); $(window).on('resize',function(){ clearTimeout(respond_timeout); respond_timeout = setTimeout(self.respond,200); //self.respond }); initialized = true; self.respond(); endLogGroup(); callback && callback(); }; /*--------------------------------------------------------------------> INIT KEY HANDLERS <--------------------------------------------------------------------*/ this.initKeyHandlers = function(){ if (self.specs.useBackButton) { window.onkeydown = function (e) { var code = e.keyCode var nonBackElements = ['input','select','textarea']; var isInputElement = nonBackElements.indexOf(e.target.tagName.toLowerCase()) != -1; if (code == 8) {//BACKBUTTON PRESSED if(isInputElement){ //return false; } else{ self.goBack(); return false; } }else if([37,39,38,40,13,16,17].indexOf(code) == -1){//set focus for alphanumeric keys if(e.altKey){//alt control switch (code) { case 70://QUICKFIND self.quickFind(); if (e.stopPropagation) e.stopPropagation(); if (e.preventDefault) e.preventDefault(); break; case 78://QUICKADD self.quickAdd(); if (e.stopPropagation) e.stopPropagation(); if (e.preventDefault) e.preventDefault(); break; } }else{ if(listMode) { var inSearchfield = false; if ($(document.activeElement) && $(document.activeElement)[0] != $('.joe-submenu-search-field')[0]) { self.overlay.find('.joe-submenu-search-field').focus(); inSearchfield = true; $('.joe-panel-content-option.keyboard-selected').removeClass('keyboard-selected'); } }else{//NOT LIST MODE, DETAILS MODE //is control key down if(e.ctrlKey || e.metaKey) { switch (code) { case 83://look for control save if(self.container.find('.joe-button.joe-quicksave-button').length) { self.updateObject(null, null, true); if (e.stopPropagation) e.stopPropagation(); if (e.preventDefault) e.preventDefault(); } break; } } } } }else{ //38 up, 40 dn,13 enter,37 left, 39 right var autocompleteField = $('.joe-text-autocomplete.active').length; if(autocompleteField){ var sel = '.joe-text-autocomplete-option.visible'+'.keyboard-selected'; //$('.joe-text-autocomplete-option.visible').length(); var keyboardSelectedIndex = ($(sel).length)? $(sel).index():-1; switch(code){ case 38://up keyboardSelectedIndex--; if(keyboardSelectedIndex > -1) { keyboardSelectOption('.joe-text-autocomplete-option.visible'); } break; case 40://down keyboardSelectedIndex++; if(keyboardSelectedIndex < $('.joe-text-autocomplete-option.visible').length) { keyboardSelectOption('.joe-text-autocomplete-option.visible'); } break; case 13://enter if(keyboardSelectedIndex != -1){ $(sel).click(); } break; } } if(listMode){ if(e.altKey){//alt control //get current index and add 1 if(self.current.subsets){ var subindex = self.current.subsets.indexOf(self.current.subset)+1;//$('joe-subset-option.active').index()+1; switch(code) { case 38://up $('joe-subset-option').eq(subindex-1).click(); break; case 40://down $('joe-subset-option').eq(subindex+1).click(); break; } } }else{ var keyboardSelectedIndex = ($('.joe-panel-content-option.keyboard-selected').length)? $('.joe-panel-content-option.keyboard-selected').index():-1; //logit(keyboardSelectedIndex); switch(code) { case 38://up keyboardSelectedIndex--; if (keyboardSelectedIndex > -1) { keyboardSelectOption('.joe-panel-content-option', top); } break; case 40://down keyboardSelectedIndex++; if (keyboardSelectedIndex < currentListItems.length) { keyboardSelectOption('.joe-panel-content-option', top); } break; case 13://enter if (keyboardSelectedIndex != -1) { $('.joe-panel-content-option.keyboard-selected').find('.joe-panel-content-option-content').click(); } break; } } }else{//DETAILS MODE if(e.altKey) { switch(code) { case 219://left case 221://right var sside = (code ==219)?'left':'right'; if(self.current.sidebars[sside].content && !self.current.sidebars[sside].hidden){ self.toggleSidebar(sside) } break; } }else if(e.ctrlKey) { switch(code) { case 37://left self.previous(); break; case 39://right self.next(); break; } }else if(code == 13){//add another row on enter click var ae = $(document.activeElement); if(ae && ae.is('input')){ var fieldobj = ae.parents('.joe-object-field'); if(fieldobj.length){ try{ fieldobj.find('.joe-plus-button').click(); }catch(e){ self.Error.add('adding new row to objectlist',e); } } } } } function keyboardSelectOption(selector,top){ $(selector+'.keyboard-selected').toggleClass('keyboard-selected'); var el = $(selector).eq(keyboardSelectedIndex); el.addClass('keyboard-selected'); self.overlay.find('.joe-submenu-search-field').blur(); // $('.joe-panel-content').scrollTop($('.joe-panel-content-option.keyboard-selected').offset().top); el[0].scrollIntoView(top); //var panel_content = self.overlay.find('.joe-panel-content'); //panel_content.animate({ scrollTop: panel_content.scrollTop()-10 }); //panel_content.scrollTop(panel_content.scrollTop()-10); } } } } }; /*--------------------------------------------------------------------> 2 | FRAMEWORK START <--------------------------------------------------------------------*/ this.getMode = function(){ if(listMode){return 'list';} return 'details'; }; this.renderFramework = function(content){ var style = 'style-variant1'; var html = '<joe-overlay class="joe-overlay sans cols-'+colCount+' '+style+' ' +((self.specs.compact && ' compact ') || '') +((self.specs.sans && ' sans ') || '') +'" data-joeindex="'+this.joe_index+'">'+ '<joe-panel class="joe-overlay-panel">'+ (content || '')+ '</joe-panel>'+ //mini '<div class="joe-mini-panel">'+ '</div>'+ '</joe-overlay>'; return html; }; this.populateFramework = function(data,setts){ /*|{ featured:true, description:'primary function for populating and rendering JOE, called by goJoe and joe.show', tags:'populate, framework, core' }|*/ self.current.cache = {}; self.overlay.removeClass('multi-edit'); var joePopulateBenchmarker = new Benchmarker(); self.current.reset = self.current.reset || {}; beginLogGroup('JOE population'); //logit('------Beginning joe population'); var specs = setts || {}; self.current.specs = setts; self.current.data = data; //clean copy for later; self.current.userSpecs = $.extend({},setts); gridMode = (self.current.specs.viewMode == 'grid')?true:false; tableMode = (self.current.specs.viewMode == 'table')?true:false; //update history 1/2 if(!self.current.specs.noHistory){ self.history.push({ /* _joeHistoryTitle:self.overlay.find('.joe-panel-title').html(), */ specs:self.current.userSpecs, data:self.current.data }); } var schema = setts.schema || ''; var profile = setts.profile || null; var callback = setts.callback || null; var datatype = setts.datatype || ''; var title = setts.title || ''; //callback if(callback){self.current.callback = callback;} else{self.current.callback = null;} /*------------------------- String data -------------------------*/ if($.type(data) == 'string' && datatype != "string" && self.getDataset(data,{boolean:true})){ if(!specs.schema && self.schemas[data]){ schema = data; } data = self.getDataset(data); } /*setup schema*/ specs.schema = this.setSchema(schema); /*------------------------- Column Count -------------------------*/ colCount = self.current.specs.colCount || (specs.schema && specs.schema.colCount) /*|| colCount*/ || 1; /*------------------------- Preformat Functions -------------------------*/ specs.preformat = (specs.schema && specs.schema.preformat) || specs.preformat || function(d){return d;}; data = specs.preformat(data); /*------------------------- Object -------------------------*/ //when object passed in if($.type(data) == 'object' || datatype =='object'){ specs.object = data; specs.menu = specs.menu || (specs.schema && specs.schema.menu) || self.specs.menu || (specs.multiedit && __defaultMultiButtons) || __defaultObjectButtons; specs.mode="object"; self.current.object = data; } /*------------------------- MultiEdit (Arrays) -------------------------*/ self.toggleMultiEditMode(specs,data); /*------------------------- Lists (Arrays) -------------------------*/ //when array passed in listMode = false; if($.type(data) == 'array' || datatype =='array'){ listMode = true; specs.list = data; specs.menu = specs.listMenu || (specs.schema && specs.schema.listMenu )|| __defaultButtons;//__defaultMultiButtons; specs.mode="list"; //TODO: filter list items here. self.current.list = data; /*------------------------- Subsets -------------------------*/ var currentSubsets; //setup subsets currentSubsets = setts.subsets || (specs.schema && specs.schema.subsets)||null; if(typeof currentSubsets == 'function'){ currentSubsets = currentSubsets(); } //a current subset selected if(self.current.specs.subset && currentSubsets && /*currentSubsets.where({name:specs.subset})*/currentSubsets.where({$or:[{name:specs.subset},{group_start:specs.subset}]}).length){ self.current.subset = currentSubsets.where({$or:[{name:specs.subset},{group_start:specs.subset}]})[0]||false; }else{ //all selected if(self.current.specs.subset == "All"){ self.current.subset = {name:"All",filter:{}} }else { //select default subset if it exists self.current.subset = (currentSubsets && currentSubsets.where({'default': true})[0]) || null; } } self.current.subsets = currentSubsets; /*------------------------- Sorting -------------------------*/ //setup sorting self.current.sorter = setts.sorter || (self.current.subset && self.current.subset.sorter)||(specs.schema && specs.schema.sorter)|| 'name'; if($.type(self.current.sorter) == 'string'){self.current.sorter = [self.current.sorter];} //self.current.object = null; } /*------------------------- Submenu -------------------------*/ if(specs.mode == 'list') { self.current.submenu = self.current.specs.listsubmenu || self.current.specs.submenu || (specs.schema && specs.schema.listSubMenu) || self.specs.listSubMenu; }else{ self.current.submenu = self.current.specs.submenu || (specs.schema && specs.schema.subMenu) || self.specs.subMenu; } if(self.current.submenu == 'none'){ self.current.submenu = null; } /*------------------------- Rendering -------------------------*/ //when rendering passed in if($.type(data) == 'string' && datatype == 'rendering'){ specs.rendering = data; specs.menu = [__replaceBtn__]; specs.mode="rendering"; self.current.rendering = specs.rendering; //specs.schema } /*------------------------- String -------------------------*/ //when string passed in else if($.type(data) == 'string' || datatype == 'string'){ specs.text = data; specs.menu = __defaultButtons; //specs.menu = [{name:'save',label:'Save Object',action:'_joe.updateObject()'}]; specs.mode="text"; self.current.text = specs.text; } //setup window title //specs.title = title || (specs.schema)? specs.schema._title : "Viewing "+specs.mode.capitalize(); specs.listWindowTitle = ( specs.list && ( specs._listMenuTitle || //specs.listWindowTitle || specs._listWindowTitle || self.getCascadingProp('listWindowTitle')|| getProperty('specs.list.windowTitle') || (specs.schema && (specs.schema._listMenuTitle || specs.schema._listWindowTitle) )) )||false; specs.title =( specs.listWindowTitle ||title || (specs.schema && (specs.schema.title||specs.schema._title)) || "Viewing "+((self.current.schema && self.current.schema.__schemaname) ||(typeof self.current.userSpecs.schema == 'string' && self.current.userSpecs.schema) || specs.mode).capitalize()); //setup profile specs.profile = (profile)? (self.specs.profiles[profile]||self.specs.joeprofile): self.specs.joeprofile; self.current.profile = specs.profile; //cleanup variables self.cleanUp(); /*--------------------------------------------------------------------> Set global view mode specs <--------------------------------------------------------------------*/ if(self.current.schema &&(self.current.schema.table||self.current.schema.tableView)){ tableSpecs = $.extend({cols:['name',self.getIDProp()]}, (self.current.schema &&(self.current.schema.table||self.current.schema.tableView) // &&(self.current.schema.table||self.current.schema.tableView).cols ) ||{}); }else{ tableSpecs = null; } /*--------------------------------------------------------------------> Framework Rendering <--------------------------------------------------------------------*/ var contentBM = new Benchmarker(); beginLogGroup('Content'); var content = self.renderEditorContent(specs); endLogGroup(); _bmResponse(contentBM,'JOE [Content]'); var chromeBM = new Benchmarker(); var html = self.renderEditorHeader(specs)+ self.renderEditorSubmenu(specs)+ content+ self.renderEditorFooter(specs)+ self.renderMessageContainer(); _bmResponse(chromeBM,'JOE [overlay-chrome]'); self.overlay.find('.joe-overlay-panel').html(html); //$('.joe-overlay-panel').html(html); //update history 2/2 - add title if(!self.current.specs.noHistory && self.history.length){ $.extend(self.history[self.history.length-1], {_joeHistoryTitle:self.overlay.find('.joe-panel-title').html()} ); } //clear ace_editors /* for (var p in _joe.ace_editors){ _joe.ace_editors[p].destroy(); } _joe.ace_editors = {};*/ //update hashlink self.updateHashLink(); //logit('Joe Populated in '+joePopulateBenchmarker.stop()+' seconds'); _bmResponse(joePopulateBenchmarker,'----Joe Populated'); endLogGroup(); return html; }; /*--------------------------------------------------------------------> 2e | FRAMEWORK END <--------------------------------------------------------------------*/ this.toggleMultiEditMode = function(specs, data){ multiEdit =(self.current.userSpecs && self.current.userSpecs.multiedit)|| false; }; /*-----------------------------> A | Header <-----------------------------*/ function createTitleObject(specs){ var specs = specs || {}; var titleObj = $.extend({},self.current.object); var list = specs.list || self.current.list; if(list){ var lcount = list.length; if(self.current.subset){ lcount = list.where(self.current.subset.filter).length; } titleObj._listCount =(lcount||'0'); titleObj._subsetName = self.current.subset && self.current.subset.name+' ' ||''; } self.current.title = specs.title || self.getCascadingProp('title') || (self.current.schema && "new "+self.current.schema.__schemaname)||'Json Object Editor'; self.current.subtitle = specs.subtitle || self.getCascadingProp('subtitle'); var title = fillTemplate(self.propAsFuncOrValue(self.current.title),titleObj); var subtitle = fillTemplate(self.propAsFuncOrValue(self.current.subtitle),titleObj); titleObj.docTitle = title; titleObj.subTitle = subtitle return titleObj; } this.Header = {} this.toggleHelpMenu = function(show,target){ } this.Header.Render = this.renderEditorHeader = function(specs){ var BM = new Benchmarker(); var specs = specs || {}; var titleObj = createTitleObject(specs); var title = titleObj.docTitle || (self.current.schema && "new "+self.current.schema.__schemaname); var subtitle = titleObj.subTitle; /* var titleObj = /!*createTitleObject(specs);*!/$.extend({},self.current.object) if(specs.list){ var lcount = specs.list.length; if(self.current.subset){ lcount = specs.list.where(self.current.subset.filter).length; } titleObj._listCount =(lcount||'0'); } self.current.title = specs.title || 'Json Object Editor'; var title = fillTemplate(self.propAsFuncOrValue(self.current.title),titleObj); titleObj.docTitle = title;*/ //show doctitle if(self.specs.documentTitle){ var doctitle = (self.specs.documentTitle === true)? self.current.title:self.propAsFuncOrValue(self.specs.documentTitle,self.current.title); document.title = fillTemplate(self.propAsFuncOrValue(doctitle),titleObj); } var close_action = specs.close_action||'onclick="getJoe('+self.joe_index+').closeButtonAction()"'; var reload_action = specs.reload_action||'onclick="getJoe('+self.joe_index+').reload()"'; function renderHeaderBackButton(){ var html = ''; if(self.history.length > 1 /*&& specs.useHeaderBackBtn*/){ //html+= '<div class="joe-header-back-btn joe-panel-header-button" onclick="getJoe('+self.joe_index+').goBack();" title="go back">&nbsp;</div>'; //html+= '<div class="jif-header-back-btn jif-panel-header-button" onclick="getJoe('+self.joe_index+').goBack();" title="back"><span class="jif-arrow-left"></span></div>'; html+= '<div class="jif-header-back-btn jif-panel-header-button" onclick="window.history.back()" title="back"><span class="jif-arrow-left"></span></div>'; } return html; } function renderHelpButton(){ var html = ''; if(specs.minimode){ return ''; } html+= '<div class="jif-panel-header-button joe-panel-help" onclick="_joe.toggleHelpMenu()" title="help">'+self.SVG.icon.help+'</div>'; return html; } var help_button = renderHelpButton() //.replace(/(<([^>]+)>)/ig,""); var speech_action = specs.speech_action||'onclick="getJoe('+self.joe_index+').Speech()"'; var reload_button = (specs.minimode)?'': '<div class="jif-panel-header-button joe-panel-reload" title="reload" '+reload_action+'><span class="jif-reload"></span></div>'; var mic_button = (!self.specs.speechRecognition||specs.minimode)?'': '<div class="jif-panel-header-button joe-panel-speech" title="speech" id="speech-button-'+self.joe_index+'">M</div>'; var close_button = '<div class="jif-panel-header-button joe-panel-close" title="close" '+close_action+'>' + '<span class="jif-close"></span>'+ '</div>'; var schema_button = (!specs.minimode && (self.current.schema && self.current.schema.menuicon && '<joe-schema-icon class="clickable" title="'+self.current.schema.__schemaname+'" onclick="goJoe(_joe.getDataset(\''+self.current.schema.__schemaname+'\'),{schema:\''+self.current.schema.__schemaname+'\'})">'+self.current.schema.menuicon+'</joe-schema-icon>')||''); var back_button = (!specs.minimode && renderHeaderBackButton() || '') var left_buttons = [ back_button, schema_button ]; var right_buttons = [ close_button, mic_button, reload_button, help_button ]; var html = //'<div class="joe-panel-header">'+ '<joe-panel-header >'+ ((specs.schema && specs.schema.subsets && self.renderSubsetselector(specs.schema)) || (specs.subsets && self.renderSubsetselector(specs)) || '')+ //'<joe-panel-header-buttons class="left-side">'+ left_buttons.join(' ')+ //'</joe-panel-header>'+ '<div class="joe-vcenter joe-panel-title-holder"><span class="joe-panel-title">'+ (('<div>'+title+'</div>').toDomElement().innerText || title || 'Json Object Editor')+ '</span></div>'+ //'<div class="joe-panel-reload joe-panel-header-button" title="reload" '+reload_action+'></div>'+ '<joe-panel-header-buttons class="right-side">'+ right_buttons.join(' ')+ '<div class="clear"></div>'+ '</joe-panel-header-buttons>'+ '<div class="clear"></div>'+ '</joe-panel-header>'; _bmResponse(BM,'[Header] rendered'); return html; }; //What happens when the user clicks the close button. this.closeButtonAction = function(prechecked){ if(!this.checkChanges()){ return; } self.history = []; self.panel.addClass('centerscreen-collapse'); self.hide(500); self.current.clear(); $(self.container).trigger({ type: "hideJoe", index:self.joe_index/*, schema: self.current.specs.schema, subset: self.current.specs.subset*/ }); self.updateHashLink(); var closeAction = self.getCascadingProp('onPanelHide'); if(closeAction){ closeAction(self.getState())} }; var goingBackFromID; var goingBackQuery; this.goBack = function(obj){ if(!this.checkChanges()){ return; } //go back to last item and highlight if(self.current.object) { var gobackItem = self.current.object[self.getIDProp()]; if (gobackItem) { goingBackFromID = gobackItem; // logit(goingBackFromID); } } //clearTimeout(self.searchTimeout ); self.history.pop(); var joespecs = self.history.pop(); if(!joespecs){ self.closeButtonAction(true); return; }else{ if(obj && $c.isArray(joespecs.data)){ var objid = obj[self.getIDProp()]; if(objid){ var query = {}; query[self.getIDProp()] = objid; var found = joespecs.data.where(query); found.length && $.extend(found[0],obj); } } if(joespecs.keyword){ goingBackQuery = joespecs.keyword; } } var specs = $.extend({},joespecs.specs); specs.filters = joespecs.filters; self.show(joespecs.data,specs); }; /* this.clearAuxiliaryData = function(){ /!*|{ featured:true, description:'cleans up variables that currently exist between a single JOE showings.', tags:'cleanup, reset', category:'core' }|*!/ self.current.list = null; self.current.subsets = null; self.current.subset = null; self.current.filters = {}; self.current.fields = []; self.current.schema = null; self.current.object = null; self.current.reset = {}; };*/ //this.current.clear = this.clearAuxiliaryData; this.cleanUp = function(){ /*|{ featured:true, description:'cleans up variables that currently exist between a single JOE showings.', tags:'cleanup, reset', category:'core' }|*/ /* if(!self._reloading){ self.current.reset = {}; }*/ self.current.fields = []; self.shiftSelecting = false; self.allSelected = false; /* for (var p in _joe.ace_editors){ _joe.ace_editors[p].destroy(); } _joe.ace_editors = {};*/ if(self.current.userSpecs && self.current.userSpecs.multiedit){ self.overlay.addClass('multi-edit'); }else{ self.overlay.removeClass('multi-edit'); } }; /*-----------------------------> B | SubMenu <-----------------------------*/ function renderSubmenuButtons(buttons){ var html = '';//<div class="joe-submenu-buttons">'; var buttons = self.propAsFuncOrValue(buttons || (listMode && self.getCascadingProp('headerListMenu')) || (!listMode && self.getCascadingProp('headerMenu'))); var content; if(buttons){ var h = self.renderMenuButtons(buttons,'joe-submenu-button'); if(h){content = true;} html+= h; } return {html:html,content:content}; // return {html:html +'</div>',content:content}; }; //self.current.submenuButtons; this.renderEditorSubmenu = function(specs) { beginLogGroup('Submenu'); var BM = new Benchmarker(); var sectionAnchors =renderSectionAnchors(); //submenu buttons var submenuButtons = renderSubmenuButtons(); if(!self.current.submenu && !sectionAnchors.count && (!listMode && !self.getCascadingProp('headerMenu'))){ return ''; } var showFilters = $c.getProperty(self.current,'userSpecs.filters') || $c.getProperty(self.current,'schema.filters') || $c.getProperty(self.current,'schema.subsets')|| false; var subSpecs = { search:true, itemcount:true, filters:showFilters, numCols:self.current.schema.columns||0 }; var userSubmenu = ($.type(self.current.submenu) != 'object')?{}:self.current.submenu; $.extend(subSpecs,userSubmenu); if(specs.mode == 'list') { var filters_obj = self.Filter.getCached(); //self.current.schema && (self.propAsFuncOrValue(self.current.schema.filters,self.current.list)) || false; var submenu = '<div class="joe-panel-submenu">' //right side + self.renderViewModeButtons(subSpecs) + self.renderColumnCountSelector(subSpecs.numCols) + self.renderSorter() //left side + ((subSpecs.filters && self.renderSubmenuFilters(subSpecs.filter)) || '') + ((subSpecs.search && self.renderSubmenuSearch(subSpecs.search)) || '') + ((subSpecs.itemcount && self.renderSubmenuItemcount(subSpecs.itemcount)) || '') +submenuButtons.html + '</div>' + "<div class='joe-filters-holder'>" + renderSubsetsDiv() + ( //( (self.current.filters && !$c.isEmpty(self.current.filters)) && renderFiltersDiv())|| (filters_obj && renderFiltersDiv()) || '') // +'<span class="jif-arrow-left"></span>' + "</div>"; }else{ var submenu = '<div class="joe-panel-submenu">' + renderSidebarToggle('left')+ renderSidebarToggle('right') +submenuButtons.html + ((sectionAnchors.count && sectionAnchors.code) || '') + '</div>';/* + "<div class='joe-filters-holder'>" // + renderSubsetsDiv() //+ (self.current.schema && (self.propAsFuncOrValue(self.current.schema.filters) && renderFiltersDiv()) || '') // +'<span class="jif-arrow-left"></span>' + "</div>";*/ } function renderOptStripeColor(opt){ var color = self.propAsFuncOrValue((opt.stripecolor||opt.stripeColor),null,null,opt); var title = ''; if(color && $c.isObject(color.title)){ title = ' title="'+color.title+'" '; color = color.color; } var h = '<joe-stripe-color '+title+(color && 'style="background-color:'+color+';"' || '')+'></joe-stripe-color>'; return h; } function renderOptBGColor(opt){ var color = self.propAsFuncOrValue((opt.bgcolor||opt.bgColor),null,null,opt); if(color && $c.isObject(color.title)){ color = color.color; } var h = '<joe-bg-color '+(color && 'style="background-color:'+color+';"' || '')+'></joe-bg-color>'; return h; } function renderOptBorderColor(opt){ var color = self.propAsFuncOrValue((opt.bordercolor||opt.borderColor),null,null,opt); if(color && $c.isObject(color.title)){ color = color.color; } var h = '<joe-border-color '+(color && 'style="border:1px solid '+color+';"' || '')+'></joe-border-color>'; return h; } function renderOptionGroupStart(opt,childDom){ var collapsed =self.propAsFuncOrValue(opt.collapsed)?'collapsed':''; if(!opt.hasOwnProperty('filter')){ var html='<joe-option-group id="'+opt.group_start+'-group" class="'+collapsed+'"><joe-menu-label onclick="$(this).parent().toggleClass(\'collapsed\');">' +(opt.display||opt.name || opt.group_start)+'</joe-menu-label>'; return html; }else{ var optdisplay = opt.display || opt.name || opt.group_start || ''; var optname = opt.id || opt.name || opt.group_start || ''; var cbox='',act,onclick; var dataname; if(childDom == 'joe-filter-option'){ dataname = ' data-filter="'+optname+'" '; cbox= '<span class ="joe-option-checkbox"></span>'; act = (self.current.filters && self.current.filters[optname])?'active':''; onclick = 'getJoe(' + self.joe_index + ').toggleFilter(\'' + optname + '\',this);_joe.Utils.stopPropagation();'; }else{ dataname = ' data-subset="'+optname+'" '; act = ((self.current.subset && self.current.subset.name == optname) || !self.current.subset && opt.name =="All") ? 'active' : ''; onclick = 'getJoe(' + self.joe_index + ').selectSubset(\'' + (optname).toString().replace(/\'/g,"\\'") + '\');'; } var optiondiv = '<'+childDom+' '+dataname+' class="'+childDom+' joe-group-option ' + act + ' " onclick='+onclick+'>' +renderOptBorderColor(opt) +renderOptBGColor(opt) +renderOptStripeColor(opt) +cbox + '<span style="position:relative;">'+optdisplay+'</span>' + '</'+childDom+'>' var html='<joe-option-group id="'+opt.group_start+'-group" class="'+collapsed+' ">' +'<joe-menu-label onclick="$(this).parent().toggleClass(\'collapsed\');">'+optiondiv+'</joe-menu-label>'; return html; } } //TODO:move to subsets filter rendering function function renderSubsetsDiv(){ var sh = '<div><joe-menu-label>Subsets</joe-menu-label>'; var act; var starting = []; if(!self.current.schema || !self.current.schema.hideAllSubset){ starting.push({name:'All',filter:{}}); } var group = null; starting.concat(_joe.current.subsets||[]).map(function(opt){ if(opt.group_start){ group = opt.group_start; sh+= renderOptionGroupStart(opt,'joe-subset-option'); }else if(opt.group_end){ sh+='</joe-option-group>'; group = null; }else{ var idval = opt.id || opt.name || '';