do not use the jquery submit method since it makes a page reload and … (#11100) (#11346)

* do not use the jquery submit method since it makes a page reload and breaks the flow
* pass the method to execute on select of an item to the typeahead directive instead of finding it via jqlite
This commit is contained in:
Matt Bargar 2017-04-21 11:06:33 -04:00 committed by GitHub
parent 239020b24e
commit 2193d7ab69
5 changed files with 53 additions and 23 deletions

View file

@ -26,7 +26,7 @@
name="queryInput"
ng-submit="filterResults()"
>
<div class="typeahead" kbn-typeahead="dashboard">
<div class="typeahead" kbn-typeahead="dashboard" on-select="filterResults()">
<div class="kuiLocalSearch">
<input
parse-query

View file

@ -23,7 +23,7 @@
name="discoverSearch"
ng-submit="fetch()"
>
<div class="typeahead" kbn-typeahead="discover">
<div class="typeahead" kbn-typeahead="discover" on-select="fetch()">
<div class="kuiLocalSearch">
<input
parse-query

View file

@ -38,7 +38,7 @@
ng-submit="fetch()"
class="fullWidth"
>
<div class="typeahead" kbn-typeahead="visualize">
<div class="typeahead" kbn-typeahead="visualize" on-select="fetch()">
<div class="kuiLocalSearch">
<input
ng-model="state.query"

View file

@ -13,11 +13,12 @@ let $parentScope;
let $typeaheadScope;
let $elem;
let typeaheadCtrl;
let onSelectStub;
let markup = '<div class="typeahead" kbn-typeahead="' + typeaheadName + '">' +
'<input type="text" placeholder="Filter..." class="form-control" ng-model="query" kbn-typeahead-input>' +
'<kbn-typeahead-items></kbn-typeahead-items>' +
'</div>';
let markup = `<div class="typeahead" kbn-typeahead="${typeaheadName}" on-select="selectItem()">
<input type="text" placeholder="Filter..." class="form-control" ng-model="query" kbn-typeahead-input>
<kbn-typeahead-items></kbn-typeahead-items>
</div>`;
const typeaheadItems = ['abc', 'def', 'ghi'];
const init = function () {
@ -48,6 +49,7 @@ const init = function () {
// Give us a scope
$parentScope = $rootScope;
$parentScope.selectItem = onSelectStub = sinon.stub();
$elem = angular.element(markup);
$compile($elem)($parentScope);
@ -63,9 +65,9 @@ describe('typeahead directive', function () {
const goodMarkup = markup;
before(function () {
markup = '<div class="typeahead" kbn-typeahead="' + typeaheadName + '">' +
'<kbn-typeahead-items></kbn-typeahead-items>' +
'</div>';
markup = `<div class="typeahead" kbn-typeahead="${typeaheadName}" on-select="selectItem()">
<kbn-typeahead-items></kbn-typeahead-items>
</div>`;
});
after(function () {
@ -76,6 +78,25 @@ describe('typeahead directive', function () {
expect(init).to.throwException(/kbn-typeahead-input must be defined/);
});
});
describe('missing on-select attribute', function () {
const goodMarkup = markup;
before(function () {
markup = `<div class="typeahead" kbn-typeahead="${typeaheadName}">
<input type="text" placeholder="Filter..." class="form-control" ng-model="query" kbn-typeahead-input />
<kbn-typeahead-items></kbn-typeahead-items>
</div>`;
});
after(function () {
markup = goodMarkup;
});
it('should throw with message', function () {
expect(init).to.throwException(/on-select must be defined/);
});
});
});
describe('internal functionality', function () {
@ -149,6 +170,20 @@ describe('typeahead directive', function () {
expect($typeaheadScope.filteredItems).not.to.contain('skrillex');
});
it('should call the on-select method on mouse click of an item', function () {
// $scope.items is set via history.add, so mock the output
typeaheadCtrl.history.add.returns(typeaheadItems);
// a single call will call history.add, which will respond with the mocked data
$typeaheadScope.inputModel.$setViewValue(typeaheadItems[0]);
typeaheadCtrl.persistEntry();
$parentScope.$digest();
$elem.find('.typeahead-item').click();
sinon.assert.called(onSelectStub);
});
});
describe('list appearance', function () {

View file

@ -18,13 +18,13 @@ typeahead.directive('kbnTypeahead', function () {
return {
restrict: 'A',
scope: {
historyKey: '@kbnTypeahead'
historyKey: '@kbnTypeahead',
onSelect: '&'
},
controllerAs: 'typeahead',
controller: function ($scope, $element, $timeout, PersistedLog, config) {
controller: function ($scope, PersistedLog, config) {
const self = this;
self.form = $element.closest('form');
self.query = '';
self.hidden = true;
self.focused = false;
@ -112,15 +112,7 @@ typeahead.directive('kbnTypeahead', function () {
self.persistEntry();
if (ev && ev.type === 'click') {
$timeout(function () {
self.submitForm();
});
}
};
self.submitForm = function () {
if (self.form.length) {
self.form.submit();
$scope.onSelect();
}
};
@ -226,7 +218,10 @@ typeahead.directive('kbnTypeahead', function () {
});
},
link: function ($scope, $el) {
link: function ($scope, $el, attrs) {
if (!_.has(attrs, 'onSelect')) {
throw new Error('on-select must be defined');
}
// should be defined via setInput() method
if (!$scope.inputModel) {
throw new Error('kbn-typeahead-input must be defined');