diff --git a/@salix/core/src/autocomplete/index.js b/@salix/core/src/autocomplete/index.js
index 007d0f1cc5..844897b3b5 100644
--- a/@salix/core/src/autocomplete/index.js
+++ b/@salix/core/src/autocomplete/index.js
@@ -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;
         },