Merge branch 'master' of ssh://git.verdnatura.es:/var/lib/git/salix
This commit is contained in:
commit
b953d7fa4f
|
@ -24,12 +24,7 @@ function template($element, $attrs, normalizer, resolve) {
|
|||
|
||||
controller.$inject = ['$http', '$element', '$attrs', '$scope', '$parse', '$document', 'vnPopover'];
|
||||
function controller($http, $element, $attrs, $scope, $parse, $document, popoverProvider) {
|
||||
let input = $element.find('input')[0];
|
||||
let popover = null;
|
||||
let data = [];
|
||||
let locked = false;
|
||||
let timeoutId = null;
|
||||
let activeOption = -1;
|
||||
|
||||
$scope.$watch($attrs.model, (newValue) => {
|
||||
if(!locked) {
|
||||
|
@ -45,8 +40,43 @@ function controller($http, $element, $attrs, $scope, $parse, $document, popoverP
|
|||
componentHandler.upgradeElement($element[0].firstChild);
|
||||
|
||||
Object.assign(this, {
|
||||
loadData: function(where, callback) {
|
||||
if(!where) where = {};
|
||||
init: function() {
|
||||
this.input = $element.find('input')[0];
|
||||
this.popover = null;
|
||||
this.data = null;
|
||||
this.showData = null;
|
||||
this.timeoutId = null;
|
||||
this.activeOption = -1;
|
||||
this.lastSearch = null;
|
||||
this.lastRequest = null;
|
||||
this.maxRows = 10;
|
||||
this.filterDelay = 350;
|
||||
this.loadData();
|
||||
},
|
||||
loadData: function(value) {
|
||||
// Optimiza la petición
|
||||
|
||||
let lastSearch = this.lastSearch;
|
||||
if(lastSearch === value) return;
|
||||
this.lastSearch = value;
|
||||
|
||||
let lastRequest = this.lastRequest;
|
||||
let requestWillSame = (
|
||||
this.data && value && lastRequest
|
||||
&& this.data.length < this.maxRows
|
||||
&& value.substr(0, lastRequest.length) == lastRequest
|
||||
);
|
||||
|
||||
if(requestWillSame) {
|
||||
this.localFilter(value);
|
||||
return;
|
||||
}
|
||||
|
||||
// Genera el filtro
|
||||
|
||||
let where = {};
|
||||
if(value) where[this.showField] = {ilike: value};
|
||||
|
||||
let fields = {};
|
||||
fields[this.valueField] = true;
|
||||
fields[this.showField] = true;
|
||||
|
@ -55,48 +85,68 @@ function controller($http, $element, $attrs, $scope, $parse, $document, popoverP
|
|||
fields: fields,
|
||||
where: where,
|
||||
order: `${this.showField} ASC`,
|
||||
limit: 10
|
||||
limit: this.maxRows
|
||||
};
|
||||
|
||||
// Envia la petición
|
||||
|
||||
this.lastRequest = value;
|
||||
let json = JSON.stringify(filter);
|
||||
|
||||
$http.get(`${this.url}?filter=${json}`).then(
|
||||
json => {
|
||||
data = json.data;
|
||||
if (callback) callback();
|
||||
},
|
||||
json => {
|
||||
data = [];
|
||||
}
|
||||
json => this.setData(json.data),
|
||||
json => this.setData([])
|
||||
);
|
||||
},
|
||||
setData: function(data) {
|
||||
this.data = data;
|
||||
this.setShowData(this.data);
|
||||
},
|
||||
localFilter: function(value) {
|
||||
let regex = new RegExp(value, 'i');
|
||||
let data = this.data.filter((item) => {
|
||||
return regex.test(item[this.showField]);
|
||||
});
|
||||
this.setShowData(data);
|
||||
},
|
||||
setShowData: function(data) {
|
||||
this.showData = data;
|
||||
|
||||
if(this.hasFocus)
|
||||
this.showPopover();
|
||||
else
|
||||
this.setValue(this.model);
|
||||
},
|
||||
showPopover: function() {
|
||||
//FIXME
|
||||
this.hidePopover();
|
||||
|
||||
popover = $document[0].createElement('ul');
|
||||
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';
|
||||
|
||||
let data = this.showData;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
popoverProvider.show(popover, input);
|
||||
popoverProvider.show(popover, this.input);
|
||||
this.popover = popover;
|
||||
},
|
||||
hidePopover: function() {
|
||||
if(!popover) return;
|
||||
activeOption = -1;
|
||||
if(!this.popover) return;
|
||||
this.activeOption = -1;
|
||||
popoverProvider.hide();
|
||||
popover = null;
|
||||
this.popover = null;
|
||||
},
|
||||
onPopoverClick: function(event) {
|
||||
let childs = popover.childNodes;
|
||||
let childs = this.popover.childNodes;
|
||||
for(let i = 0; i < childs.length; i++)
|
||||
if(childs[i] === event.target) {
|
||||
this.selectOptionByIndex(i);
|
||||
|
@ -110,45 +160,48 @@ function controller($http, $element, $attrs, $scope, $parse, $document, popoverP
|
|||
event.preventDefault();
|
||||
},
|
||||
onFocus: function() {
|
||||
input.select();
|
||||
this.hasFocus = true;
|
||||
this.input.select();
|
||||
this.showPopover();
|
||||
},
|
||||
onBlur: function() {
|
||||
this.hasFocus = false;
|
||||
this.hidePopover();
|
||||
},
|
||||
onKeypress: function(event) {
|
||||
onKeydown: function(event) {
|
||||
switch(event.keyCode) {
|
||||
case 13: // Enter
|
||||
if(popover && activeOption != -1) {
|
||||
this.selectOptionByIndex(activeOption);
|
||||
if(this.popover && this.activeOption != -1) {
|
||||
this.putValue(this.showData[this.activeOption]);
|
||||
this.hidePopover();
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case 27: // Escape
|
||||
this.hidePopover();
|
||||
break;
|
||||
case 38: // Arrow up
|
||||
this.activateOption(activeOption-1);
|
||||
return;
|
||||
this.activateOption(this.activeOption-1);
|
||||
break;
|
||||
case 40: // Arrow down
|
||||
this.activateOption(activeOption+1);
|
||||
this.activateOption(this.activeOption+1);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
},
|
||||
onClick: function(event) {
|
||||
if(!popover)
|
||||
this.showPopover();
|
||||
if(!this.popover) this.showPopover();
|
||||
},
|
||||
onKeyup: function(event) {
|
||||
if(!this.isKeycodePrintable(event.keyCode))
|
||||
return;
|
||||
|
||||
if(timeoutId) clearTimeout(timeoutId);
|
||||
timeoutId = setTimeout(() => this.onTimeout(), 300);
|
||||
if(!this.isKeycodePrintable(event.keyCode)) return;
|
||||
if(this.timeoutId) clearTimeout(this.timeoutId);
|
||||
this.timeoutId = setTimeout(() => this.onTimeout(), this.filterDelay);
|
||||
},
|
||||
onTimeout: function() {
|
||||
let value = input.value;
|
||||
let filter = {};
|
||||
filter[this.showField] = {ilike: value};
|
||||
this.loadData(filter, () => this.showPopover());
|
||||
timeoutId = null;
|
||||
this.loadData(this.input.value);
|
||||
this.timeoutId = null;
|
||||
},
|
||||
isKeycodePrintable: function(keyCode) {
|
||||
return keyCode == 32 // Spacebar
|
||||
|
@ -160,13 +213,13 @@ function controller($http, $element, $attrs, $scope, $parse, $document, popoverP
|
|||
|| (keyCode > 218 && keyCode < 223); // [\]'
|
||||
},
|
||||
activateOption: function(index) {
|
||||
if(!popover)
|
||||
if(!this.popover)
|
||||
this.showPopover();
|
||||
|
||||
let childs = popover.childNodes;
|
||||
let childs = this.popover.childNodes;
|
||||
|
||||
if(activeOption >= 0)
|
||||
childs[activeOption].className = '';
|
||||
if(this.activeOption >= 0)
|
||||
childs[this.activeOption].className = '';
|
||||
|
||||
if(index >= childs.length)
|
||||
index = 0;
|
||||
|
@ -176,30 +229,37 @@ function controller($http, $element, $attrs, $scope, $parse, $document, popoverP
|
|||
if (index >= 0)
|
||||
childs[index].className = 'active';
|
||||
|
||||
activeOption = index;
|
||||
this.activeOption = index;
|
||||
},
|
||||
setValue: function(value) {
|
||||
let index = -1;
|
||||
let data = this.data;
|
||||
|
||||
if(value && data)
|
||||
for(let i = 0; i < data.length; i++)
|
||||
if(data[i][this.valueField] == value) {
|
||||
this.selectOptionByIndex(i);
|
||||
this.putValue(data[i]);
|
||||
return;
|
||||
}
|
||||
|
||||
this.selectOptionByIndex(-1);
|
||||
this.putValue(null);
|
||||
},
|
||||
selectOptionByIndex: function(index) {
|
||||
let data = this.data;
|
||||
|
||||
if(data && index >= 0 && index < data.length)
|
||||
this.putValue(data[index]);
|
||||
else
|
||||
this.putValue(null);
|
||||
},
|
||||
putValue: function(item) {
|
||||
let value;
|
||||
|
||||
if(index >= 0 && index < data.length) {
|
||||
let item = data[index];
|
||||
input.value = item[this.showField];
|
||||
if(item) {
|
||||
this.input.value = item[this.showField];
|
||||
value = item[this.valueField];
|
||||
}
|
||||
else {
|
||||
input.value = '';
|
||||
this.input.value = '';
|
||||
value = undefined;
|
||||
}
|
||||
|
||||
|
@ -215,5 +275,5 @@ function controller($http, $element, $attrs, $scope, $parse, $document, popoverP
|
|||
}
|
||||
});
|
||||
|
||||
this.loadData(null, () => this.setValue(this.model));
|
||||
this.init();
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
rule="*[rule]*"
|
||||
*[enabled]*
|
||||
*[focus]*
|
||||
ng-keypress="$ctrl.onKeypress($event)"
|
||||
ng-keydown="$ctrl.onKeydown($event)"
|
||||
ng-click="$ctrl.onClick($event)"
|
||||
ng-keyup="$ctrl.onKeyup($event)"
|
||||
ng-focus="$ctrl.onFocus($event)"
|
||||
|
|
Loading…
Reference in New Issue