Combo v7
This commit is contained in:
parent
8ded908204
commit
5da711e98d
|
@ -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);
|
||||
}
|
||||
|
||||
popoverProvider.show(popover, this.input);
|
||||
this.popover = popover;
|
||||
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;
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue