UNPKG

kibana-with-account

Version:

kibana-with-account is develop based kibana project

242 lines (197 loc) 6.86 kB
define(function (require) { var _ = require('lodash'); var typeahead = require('ui/modules').get('kibana/typeahead'); require('ui/typeahead/typeahead.less'); require('ui/typeahead/_input'); require('ui/typeahead/_items'); typeahead.directive('kbnTypeahead', function () { var keyMap = { ESC: 27, UP: 38, DOWN: 40, TAB: 9, ENTER: 13 }; return { restrict: 'A', scope: { historyKey: '@kbnTypeahead' }, controllerAs: 'typeahead', controller: function ($scope, $element, $timeout, PersistedLog, config) { var self = this; self.form = $element.closest('form'); self.query = ''; self.hidden = true; self.focused = false; self.mousedOver = false; // instantiate history and add items to the scope self.history = new PersistedLog('typeahead:' + $scope.historyKey, { maxLength: config.get('history:limit'), filterDuplicates: true }); $scope.items = self.history.get(); $scope.filteredItems = []; self.setInputModel = function (model) { $scope.inputModel = model; // watch for changes to the query parameter, delegate to typeaheadCtrl $scope.$watch('inputModel.$viewValue', self.filterItemsByQuery); }; self.setHidden = function (hidden) { self.hidden = !!(hidden); }; self.setFocused = function (focused) { self.focused = !!(focused); }; self.setMouseover = function (mousedOver) { self.mousedOver = !!(mousedOver); }; // activation methods self.activateItem = function (item) { self.active = item; }; self.getActiveIndex = function () { if (!self.active) { return; } return $scope.filteredItems.indexOf(self.active); }; self.getItems = function () { return $scope.filteredItems; }; self.activateNext = function () { var index = self.getActiveIndex(); if (index == null) { index = 0; } else if (index < $scope.filteredItems.length - 1) { ++index; } self.activateItem($scope.filteredItems[index]); }; self.activatePrev = function () { var index = self.getActiveIndex(); if (index > 0 && index != null) { --index; } else if (index === 0) { self.active = false; return; } self.activateItem($scope.filteredItems[index]); }; self.isActive = function (item) { return item === self.active; }; // selection methods self.selectItem = function (item, ev) { self.hidden = true; self.active = false; $scope.inputModel.$setViewValue(item); $scope.inputModel.$render(); self.persistEntry(); if (ev && ev.type === 'click') { $timeout(function () { self.submitForm(); }); } }; self.submitForm = function () { if (self.form.length) { self.form.submit(); } }; self.persistEntry = function () { if ($scope.inputModel.$viewValue.length) { // push selection into the history $scope.items = self.history.add($scope.inputModel.$viewValue); } }; self.selectActive = function () { if (self.active) { self.selectItem(self.active); } }; self.keypressHandler = function (ev) { var keyCode = ev.which || ev.keyCode; if (self.focused) { self.hidden = false; } // hide on escape if (_.contains([keyMap.ESC], keyCode)) { self.hidden = true; self.active = false; } // change selection with arrow up/down // on down key, attempt to load all items if none are loaded if (_.contains([keyMap.DOWN], keyCode) && $scope.filteredItems.length === 0) { $scope.filteredItems = $scope.items; $scope.$digest(); } else if (_.contains([keyMap.UP, keyMap.DOWN], keyCode)) { if (self.isVisible() && $scope.filteredItems.length) { ev.preventDefault(); if (keyCode === keyMap.DOWN) { self.activateNext(); } else { self.activatePrev(); } } } // persist selection on enter, when not selecting from the list if (_.contains([keyMap.ENTER], keyCode)) { if (!self.active) { self.persistEntry(); } } // select on enter or tab if (_.contains([keyMap.ENTER, keyMap.TAB], keyCode)) { self.selectActive(); self.hidden = true; } }; self.filterItemsByQuery = function (query) { // cache query so we can call it again if needed if (query) { self.query = query; } // if the query is empty, clear the list items if (!self.query.length) { $scope.filteredItems = []; return; } // update the filteredItems using the query var beginningMatches = $scope.items.filter(function (item) { return item.indexOf(query) === 0; }); var otherMatches = $scope.items.filter(function (item) { return item.indexOf(query) > 0; }); $scope.filteredItems = beginningMatches.concat(otherMatches); }; self.isVisible = function () { return !self.hidden && ($scope.filteredItems.length > 0) && (self.focused || self.mousedOver); }; // handle updates to parent scope history $scope.$watch('items', function (items) { if (self.query) { self.filterItemsByQuery(self.query); } }); // watch for changes to the filtered item list $scope.$watch('filteredItems', function (filteredItems) { // if list is empty, or active item is missing, unset active item if (!filteredItems.length || !_.contains(filteredItems, self.active)) { self.active = false; } }); }, link: function ($scope, $el, attr) { // should be defined via setInput() method if (!$scope.inputModel) { throw new Error('kbn-typeahead-input must be defined'); } $scope.$watch('typeahead.isVisible()', function (vis) { $el.toggleClass('visible', vis); }); } }; }); });