json-object-editor
Version:
JOE the Json Object Editor | Platform Edition
149 lines (134 loc) • 5.38 kB
JavaScript
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);
// })