This commit is contained in:
Juan Ferrer Toribio 2017-01-22 23:21:02 +01:00
parent 8ded908204
commit 5da711e98d
1 changed files with 92 additions and 56 deletions

View File

@ -52,22 +52,27 @@ function controller($http, $element, $attrs, $scope, $parse, $document, popoverP
this.timeoutId = null;
this.lastSearch = null;
this.lastRequest = null;
this.currentRequest = null;
this.moreData = false;
this.activeOption = -1;
this.maxRows = 10;
this.filterDelay = 350;
this.requestDelay = 350;
this.requestItem();
},
loadData: function(textFilter) {
let lastSearch = this.lastSearch;
if(lastSearch === textFilter) return;
textFilter = textFilter ? textFilter : '';
if(this.lastSearch === textFilter) {
this.popoverDataReady();
return;
}
this.lastSearch = textFilter;
let lastRequest = this.lastRequest;
let requestWillSame = (
this.data && textFilter && lastRequest && !this.moreData
&& textFilter.substr(0, lastRequest.length) == lastRequest
);
let requestWillSame = lastRequest !== null
&& !this.moreData
&& textFilter.substr(0, lastRequest.length) === lastRequest;
if(requestWillSame)
this.localFilter(textFilter);
@ -80,36 +85,12 @@ function controller($http, $element, $attrs, $scope, $parse, $document, popoverP
fields[this.showField] = true;
return fields;
},
requestItem: function() {
if(!this.model) return;
let where = {};
where[this.valueField] = this.model;
let filter = {
fields: this.getRequestFields(),
where: where,
};
let json = JSON.stringify(filter);
$http.get(`${this.url}?filter=${json}`).then(
json => this.onItemRequest(json.data),
json => this.onItemRequest(null)
);
},
onItemRequest: function(data) {
if(data && data.length > 0)
this.showItem(data[0]);
else
this.showItem(null);
},
requestData: function(textFilter, append) {
let where = {};
if(textFilter) where[this.showField] = {ilike: textFilter};
let skip = 0;
if(textFilter)
where[this.showField] = {ilike: textFilter};
if(append && this.data)
skip = this.data.length;
@ -121,15 +102,20 @@ function controller($http, $element, $attrs, $scope, $parse, $document, popoverP
limit: this.maxRows
};
this.lastRequest = textFilter;
this.lastRequest = textFilter ? textFilter : '';
let json = JSON.stringify(filter);
$http.get(`${this.url}?filter=${json}`).then(
if(this.currentRequest)
this.currentRequest.resolve();
this.currentRequest = $http.get(`${this.url}?filter=${json}`);
this.currentRequest.then(
json => this.onRequest(json.data, append),
json => this.onRequest([])
);
},
onRequest: function(data, append) {
this.currentRequest = null;
this.moreData = data.length >= this.maxRows;
if(!append || !this.data)
@ -148,39 +134,46 @@ function controller($http, $element, $attrs, $scope, $parse, $document, popoverP
},
setPopoverData: function(data) {
this.popoverData = data;
this.popoverDataReady();
},
popoverDataReady: function() {
if(this.hasFocus)
this.showPopover();
},
showPopover: function() {
if(!this.data) return;
//FIXME
this.hidePopover();
let popover = $document[0].createElement('ul');
popover.addEventListener('click',
(e) => this.onPopoverClick(e));
popover.addEventListener('mousedown',
(e) => this.onPopoverMousedown(e));
popover.className = 'vn-autocomplete';
let fragment = $document[0].createDocumentFragment();
let data = this.popoverData;
for(let i = 0; i < data.length; i++) {
let li = $document[0].createElement('li');
li.appendChild($document[0].createTextNode(data[i][this.showField]));
popover.appendChild(li);
fragment.appendChild(li);
}
if(this.moreData) {
let li = $document[0].createElement('li');
li.appendChild($document[0].createTextNode('Load more'));
li.className = 'load-more';
popover.appendChild(li);
fragment.appendChild(li);
}
if (!this.popover) {
let popover = $document[0].createElement('ul');
popover.addEventListener('click',
(e) => this.onPopoverClick(e));
popover.addEventListener('mousedown',
(e) => this.onPopoverMousedown(e));
popover.className = 'vn-autocomplete';
popover.appendChild(fragment);
popoverProvider.show(popover, this.input);
this.popover = popover;
}
else {
this.popover.innerHTML = '';
this.popover.appendChild(fragment);
}
},
hidePopover: function() {
if(!this.popover) return;
@ -224,6 +217,7 @@ function controller($http, $element, $attrs, $scope, $parse, $document, popoverP
},
onBlur: function() {
this.hasFocus = false;
this.restoreShowValue();
this.hidePopover();
},
onKeydown: function(event) {
@ -232,7 +226,8 @@ function controller($http, $element, $attrs, $scope, $parse, $document, popoverP
this.selectPopoverOption(this.activeOption);
break;
case 27: // Escape
this.hidePopover();
this.restoreShowValue();
this.input.select();
break;
case 38: // Arrow up
this.activateOption(this.activeOption-1);
@ -249,7 +244,7 @@ function controller($http, $element, $attrs, $scope, $parse, $document, popoverP
onKeyup: function(event) {
if(!this.isKeycodePrintable(event.keyCode)) return;
if(this.timeoutId) clearTimeout(this.timeoutId);
this.timeoutId = setTimeout(() => this.onTimeout(), this.filterDelay);
this.timeoutId = setTimeout(() => this.onTimeout(), this.requestDelay);
},
onTimeout: function() {
this.loadData(this.input.value);
@ -264,22 +259,63 @@ function controller($http, $element, $attrs, $scope, $parse, $document, popoverP
|| (keyCode > 185 && keyCode < 193) // ;=,-./`
|| (keyCode > 218 && keyCode < 223); // [\]'
},
restoreShowValue: function() {
this.putItem(this.item);
},
requestItem: function() {
if(!this.model) return;
let where = {};
where[this.valueField] = this.model;
let filter = {
fields: this.getRequestFields(),
where: where,
};
let json = JSON.stringify(filter);
$http.get(`${this.url}?filter=${json}`).then(
json => this.onItemRequest(json.data),
json => this.onItemRequest(null)
);
},
onItemRequest: function(data) {
if(data && data.length > 0)
this.showItem(data[0]);
else
this.showItem(null);
},
activateOption: function(index) {
if(!this.popover)
this.showPopover();
let childs = this.popover.childNodes;
let popover = this.popover;
let childs = popover.childNodes;
let len = this.popoverData.length;
if(this.activeOption >= 0)
childs[this.activeOption].className = '';
if(index >= childs.length)
if(index >= len)
index = 0;
else if(index < 0)
index = childs.length - 1;
index = len - 1;
if (index >= 0)
childs[index].className = 'active';
if (index >= 0) {
let opt = childs[index];
let top = popover.scrollTop;
let height = popover.clientHeight;
if(opt.offsetTop + opt.offsetHeight > top + height)
top = opt.offsetTop + opt.offsetHeight - height;
else if(opt.offsetTop < top)
top = opt.offsetTop;
opt.className = 'active';
popover.scrollTop = top;
}
this.activeOption = index;
},