UNPKG

json-object-editor

Version:

JOE the Json Object Editor | Platform Edition

149 lines (134 loc) 5.38 kB
class JoeAutocomplete extends HTMLElement { constructor() { super(); } static get observedAttributes() { return []; } connectedCallback() { var st = new Date().getTime(); var self = this; this.fieldNode = this.closest('joe-field'); //this.fieldNode.setAttribute('tabindex','-1'); this.input = this.previousSibling; // this.fieldNode.addEventListener("focusout", (event) => { // this.hide(); // }); // this.fieldNode.addEventListener("focus", (event) => { // this.show(); // }); this.classList.add('joe-autocomplete'); this.schemaObj = _joe.schemas[this.getAttribute('schema')]; this.field = this.getAttribute('field'); this.itemId = this.getAttribute('itemId'); this.idprop = this.getAttribute('idprop') || this.schemaObj.idprop; this.propObj = _joe.getField(this.field); this.joeIndex = this.getAttribute('joe-index'); this.values = this.propObj.values; if(typeof this.values == "function"){ this.values = this.values(_joe.current.object); } if($.type(this.values) == 'string' && _joe.getDataset(this.values)){ this.values = _joe.getDataset(this.values); } this.lookup ={}; this.autocompleteSpecs = this.propObj.autocomplete||{ template:this.propObj.autocomplete_template||this.propObj.template ||'<joe-title>${name}</joe-title><joe-subtext>${info}</joe-subtext>' }; this.template = this.autocompleteSpecs.template; //this.values.map(v=>{ for(var i =0;i<this.values.length;i++){ let v = this.values[i]; let schema = (v.itemtype && _joe.schemas[v.itemtype]) || this.schemaObj; var searchable = schema.searchable || this.autocompleteSpecs.searchable || ['name','id','info']; let haystack = searchable.map(s=>{ return v[s]}).join(' ').replace( /,/,' ').toLowerCase(); this.lookup[v[this.idprop]] = haystack; } //`${v.name} ${v.id} ${v.info} `.replace( /,/,' ').toLowerCase(); //}) // _joe.propAsFuncOrValue(this.propObj.values); var el = new Date().getTime() - st; this.innerHTML = `<joe-subtext data-role="counter">${this.values.length} options [${el} ms]</joe-subtext><autocomplete-options></autocomplete-options>`; this.counter = this.querySelector('joe-subtext[data-role=counter]'); this.autocompleteOptions = this.querySelector('autocomplete-options'); this.hide(); } search(query){ if(!query.length){ this.classList.remove('active'); this.hide(); return; } //find elements in values that match var needles = query.toLowerCase().replace( /,/,' ').split(' '); this.show(); var opts = this.values.filter(v=>{ if(!needles.length){ return true; } for(var n = 0, tot = needles.length; n<tot; n++){ if(this.autocompleteSpecs.text){ if(v.indexOf(needles[n]) == -1){//needle not in haystack return false; } }else{ if(this.lookup[v[this.idprop]].indexOf(needles[n]) == -1){//needle not in haystack return false; } } } return true; }) this.renderOptions(opts); this.counter.innerHTML = opts.length+' options'; this.classList.add('active'); } renderOptions(opts) { var autocomplete = this.autocompleteSpecs; var html =''; var ac_opt; var ac_id, ac_title; var max = Math.min(20,opts.length); for(var v = 0, len = max; v < len; v++){ ac_opt = opts[v]; if(this.autocompleteSpecs.text){ html +=`<div class="joe-text-autocomplete-option" onclick="this.closest('joe-autocomplete').clickText('${ac_opt}')" data-value="${ac_opt}"> ${ac_opt} </div>`; }else{ //ac_opt = ($.type(this.values[v]) == "object")? // this.values[v]: // {id:this.values[v],name:this.values[v]}; // ac_title = fillTemplate(_joe.propAsFuncOrValue(autocomplete.template,ac_opt,null,_joe.current.object),ac_opt); // ac_id = (autocomplete.value && fillTemplate(_joe.propAsFuncOrValue(autocomplete.value,ac_opt),ac_opt)) // ||(autocomplete.idprop && ac_opt[autocomplete.idprop]) // ||ac_opt._id||ac_opt.id||ac_opt.name; let schema = (ac_opt.itemtype && _joe.schemas[ac_opt.itemtype]) || this.schemaObj; ac_id = ac_opt[this.idprop]; ac_title = this.lookup[ac_id]; html+=`<div class="joe-text-autocomplete-option" onclick="getJoe(${this.joeIndex}).autocompleteTextFieldOptionClick(this);" data-value="${ac_id}"> ${_joe.schemas[schema.name] && _joe.schemas[schema.name].menuicon || ''} ${fillTemplate(_joe.propAsFuncOrValue(this.template,ac_opt),ac_opt)} </div>`; } } this.autocompleteOptions.innerHTML = html; } clickText(text){ //set input value this.input.value = text; this.input.focus(); this.hide(); } attributeChangedCallback(attr, oldValue, newValue) { } disconnectedCallback() {} } // window.addEventListener('load', function(){ window.customElements.define("joe-autocomplete", JoeAutocomplete); // })