diff --git a/@salix/core/src/autocomplete/index.js b/@salix/core/src/autocomplete/index.js index cb153da0e6..5d0ccf7e22 100644 --- a/@salix/core/src/autocomplete/index.js +++ b/@salix/core/src/autocomplete/index.js @@ -1,82 +1,154 @@ import {module} from '../module'; export {factory as mdlFactory} from './index.mdl'; -import * as resolveFactory from '../resolveDefaultComponents'; -import * as normalizerFactory from '../inputAttrsNormalizer'; require('./style.css'); -directive.$inject = [resolveFactory.NAME, normalizerFactory.NAME]; -export function directive(resolve, normalizer) { - return { - restrict: 'E', - transclude: true, - scope: { - url: '@', - showField: '@', - valueField: '@', - model: '<' - }, - template: function(element, attrs) { - normalizer.normalize(attrs); - return resolve.getTemplate('autocomplete', attrs); - }, - link: function(scope, element, attrs) { - scope.$watch(attrs.model, () => { - let mdlField = element[0].firstChild.MaterialTextfield; - if (mdlField) - mdlField.updateClasses_(); - }); - componentHandler.upgradeElement(element[0].firstChild); - }, - controller: controller - }; +export const component = { + restrict: 'E', + transclude: true, + bindings: { + url: '@', + showField: '@', + valueField: '@', + model: '<' + }, + template: template, + controller: controller +}; +module.component('vnAutocomplete', component); + +template.$inject = ['$element', '$attrs', 'vnInputAttrsNormalizer', 'vnResolveDefaultComponent']; +function template($element, $attrs, normalizer, resolve) { + normalizer.normalize($attrs); + return resolve.getTemplate('autocomplete', $attrs); } -module.directive('vnAutocomplete', directive); controller.$inject = ['$http', '$element', '$attrs', '$scope', '$parse', '$document', 'vnPopover']; -export function controller($http, $element, $attrs, $scope, $parse, $document, popover) { +function controller($http, $element, $attrs, $scope, $parse, $document, popover) { let dropdown = null; let input = $element.find('input'); let data = []; let locked = false; - - $http.get($scope.url).then( - json => { - data = json.data; - setTimeout(function() { - $scope.setValue($scope.model); - }); - }, - json => {data = [];} - ); + let timeoutId = null; $scope.$watch($attrs.model, (newValue) => { if(!locked) { locked = true; - $scope.setValue(newValue); + this.setValue(newValue); locked = false; } - }); - $scope.setValue = function(value) { + let mdlField = $element[0].firstChild.MaterialTextfield; + if (mdlField) + mdlField.updateClasses_(); + }); + componentHandler.upgradeElement($element[0].firstChild); + + this.loadData = function(where, callback) { + if(!where) where = {}; + let fields = {}; + fields[this.valueField] = true; + fields[this.showField] = true; + + let filter = { + fields: fields, + where: where, + order: `${this.showField} ASC`, + limit: 5 + }; + + let json = JSON.stringify(filter); + + $http.get(`${this.url}?filter=${json}`).then( + json => { + data = json.data; + if (callback) callback(); + }, + json => { + data = []; + } + ); + }; + + this.onClick = function() { + input[0].select(); + this.showDropdown(); + }; + + this.showDropdown = function() { + //FIXME + popover.hide(); + + dropdown = $document[0].createElement('ul'); + dropdown.addEventListener('click', + (e) => this.onOptionClick(e)); + dropdown.className = 'vn-dropdown'; + + for(let i = 0; i < data.length; i++) { + let li = $document[0].createElement('li'); + li.tabIndex = 0; + li.appendChild($document[0].createTextNode(data[i][this.showField])); + dropdown.appendChild(li); + } + + popover.show(dropdown, input); + } + + this.onOptionClick = function(event) { + popover.hide(); + + let childs = dropdown.childNodes; + for(let i = 0; i < childs.length; i++) + if(childs[i] === event.target) { + this.selectOptionByIndex(i); + break; + } + } + + this.onTimeout = function() { + let value = input.val(); + let filter = {}; + filter[this.showField] = {ilike: value}; + this.loadData(filter, () => this.showDropdown()); + clearTimeout(timeoutId); + timeoutId = null; + } + + this.onKeyup = function(event) { + if(timeoutId) clearTimeout(timeoutId); + console.log(event.keyCode); + + switch(event.keyCode) { + case 13: // Enter + this.selectOptionByIndex(0); + return; + case 40: // Arrow down + dropdown.firstChild.focus(); + return; + } + + timeoutId = setTimeout(() => this.onTimeout(), 300); + }; + + this.setValue = function(value) { let index = -1; if(value && data) for(let i = 0; i < data.length; i++) - if(data[i][$scope.valueField] == value) { - $scope.selectOptionByIndex(i); + if(data[i][this.valueField] == value) { + this.selectOptionByIndex(i); return; } - $scope.selectOptionByIndex(-1); + this.selectOptionByIndex(-1); } - $scope.selectOptionByIndex = function(index) { + this.selectOptionByIndex = function(index) { let value; - if(index >= 0) { + if(index >= 0 && index < data.length) { let item = data[index]; - input.val(item[$scope.showField]); - value = item[$scope.valueField]; + input.val(item[this.showField]); + value = item[this.valueField]; } else { input.val(''); @@ -92,33 +164,7 @@ export function controller($http, $element, $attrs, $scope, $parse, $document, p } } - function onOptionClick(event) { - popover.hide(); - - let childs = dropdown.childNodes; - for(let i = 0; i < childs.length; i++) - if(childs[i] === event.target) { - $scope.selectOptionByIndex(i); - break; - } - } - - $scope.onClick = () => { - dropdown = $document[0].createElement('ul'); - dropdown.addEventListener('click', onOptionClick); - dropdown.className = 'vn-dropdown'; - - for(let i = 0; i < data.length; i++) { - let item = $document[0].createElement('li'); - item.className = 'vn-dropdown-item'; - item.appendChild($document[0].createTextNode(data[i][$scope.showField])); - dropdown.appendChild(item); - } - - popover.show(dropdown, input); - }; - - $scope.onKeypress = () => { - console.log(input.val()); - }; + this.loadData(null, () => { + setTimeout(() => this.setValue(this.model)); + }); } diff --git a/@salix/core/src/autocomplete/index.mdl.html b/@salix/core/src/autocomplete/index.mdl.html index 04ef50d81f..6b72b2e9a5 100644 --- a/@salix/core/src/autocomplete/index.mdl.html +++ b/@salix/core/src/autocomplete/index.mdl.html @@ -1,4 +1,4 @@ -