Skip to content
This repository has been archived by the owner on May 29, 2019. It is now read-only.

Commit

Permalink
feat(typeahead): add event object to onSelect
Browse files Browse the repository at this point in the history
- Add support for `$event` in expression with `onSelect`

Closes #5165
  • Loading branch information
deeg authored and wesleycho committed Jan 8, 2016
1 parent 3ef8992 commit 3e876b8
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 21 deletions.
4 changes: 2 additions & 2 deletions src/typeahead/docs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ The typeahead directives provide several attributes:
_(Defaults: angular.noop)_ :
Binding to a variable that indicates if no matching results were found

* `typeahead-on-select($item, $model, $label)`
* `typeahead-on-select($item, $model, $label, $event)`
_(Defaults: null)_ :
A callback executed when a match is selected
A callback executed when a match is selected. $event can be undefined if selection not triggered from a user event.

* `typeahead-select-on-exact`
_(Defaults: false)_ :
Expand Down
6 changes: 4 additions & 2 deletions src/typeahead/test/typeahead.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -478,12 +478,13 @@ describe('typeahead tests', function() {
});

it('should invoke select callback on select', function() {
$scope.onSelect = function($item, $model, $label) {
$scope.onSelect = function($item, $model, $label, $event) {
$scope.$item = $item;
$scope.$model = $model;
$scope.$label = $label;
$scope.$event = $event;
};
var element = prepareInputEl('<div><input ng-model="result" typeahead-on-select="onSelect($item, $model, $label)" uib-typeahead="state.code as state.name for state in states | filter:$viewValue"></div>');
var element = prepareInputEl('<div><input ng-model="result" typeahead-on-select="onSelect($item, $model, $label, $event)" uib-typeahead="state.code as state.name for state in states | filter:$viewValue"></div>');

changeInputValueTo(element, 'Alas');
triggerKeyDown(element, 13);
Expand All @@ -492,6 +493,7 @@ describe('typeahead tests', function() {
expect($scope.$item).toEqual($scope.states[0]);
expect($scope.$model).toEqual('AL');
expect($scope.$label).toEqual('Alaska');
expect($scope.$event.type).toEqual("keydown");
});

it('should correctly update inputs value on mapping where label is not derived from the model', function() {
Expand Down
33 changes: 17 additions & 16 deletions src/typeahead/typeahead.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.debounce', 'ui.bootstrap
id: popupId,
matches: 'matches',
active: 'activeIdx',
select: 'select(activeIdx)',
select: 'select(activeIdx, evt)',
'move-in-progress': 'moveInProgress',
query: 'query',
position: 'position',
Expand Down Expand Up @@ -202,7 +202,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.debounce', 'ui.bootstrap
return false;
};

var getMatchesAsync = function(inputValue) {
var getMatchesAsync = function(inputValue, evt) {
var locals = {$viewValue: inputValue};
isLoadingSetter(originalScope, true);
isNoResultsSetter(originalScope, false);
Expand Down Expand Up @@ -238,10 +238,10 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.debounce', 'ui.bootstrap
if (selectOnExact && scope.matches.length === 1 && inputIsExactMatch(inputValue, 0)) {
if (angular.isNumber(scope.debounceUpdate) || angular.isObject(scope.debounceUpdate)) {
$$debounce(function() {
scope.select(0);
scope.select(0, evt);
}, angular.isNumber(scope.debounceUpdate) ? scope.debounceUpdate : scope.debounceUpdate['default']);
} else {
scope.select(0);
scope.select(0, evt);
}
}

Expand Down Expand Up @@ -329,7 +329,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.debounce', 'ui.bootstrap
isOpenSetter(originalScope, isOpen);
};

scope.select = function(activeIdx) {
scope.select = function(activeIdx, evt) {
//called from within the $digest() cycle
var locals = {};
var model, item;
Expand All @@ -344,7 +344,8 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.debounce', 'ui.bootstrap
onSelectCallback(originalScope, {
$item: item,
$model: model,
$label: parserResult.viewMapper(originalScope, locals)
$label: parserResult.viewMapper(originalScope, locals),
$event: evt
});

resetMatches();
Expand Down Expand Up @@ -378,10 +379,10 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.debounce', 'ui.bootstrap
scope.$apply(function () {
if (angular.isNumber(scope.debounceUpdate) || angular.isObject(scope.debounceUpdate)) {
$$debounce(function() {
scope.select(scope.activeIdx);
scope.select(scope.activeIdx, evt);
}, angular.isNumber(scope.debounceUpdate) ? scope.debounceUpdate : scope.debounceUpdate['default']);
} else {
scope.select(scope.activeIdx);
scope.select(scope.activeIdx, evt);
}
});
break;
Expand All @@ -404,25 +405,25 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.debounce', 'ui.bootstrap
}
});

element.bind('focus', function () {
element.bind('focus', function (evt) {
hasFocus = true;
if (minLength === 0 && !modelCtrl.$viewValue) {
$timeout(function() {
getMatchesAsync(modelCtrl.$viewValue);
getMatchesAsync(modelCtrl.$viewValue, evt);
}, 0);
}
});

element.bind('blur', function() {
element.bind('blur', function(evt) {
if (isSelectOnBlur && scope.matches.length && scope.activeIdx !== -1 && !selected) {
selected = true;
scope.$apply(function() {
if (angular.isObject(scope.debounceUpdate) && angular.isNumber(scope.debounceUpdate.blur)) {
$$debounce(function() {
scope.select(scope.activeIdx);
scope.select(scope.activeIdx, evt);
}, scope.debounceUpdate.blur);
} else {
scope.select(scope.activeIdx);
scope.select(scope.activeIdx, evt);
}
});
}
Expand Down Expand Up @@ -585,14 +586,14 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.debounce', 'ui.bootstrap
scope.active = matchIdx;
};

scope.selectMatch = function(activeIdx) {
scope.selectMatch = function(activeIdx, evt) {
var debounce = scope.debounce();
if (angular.isNumber(debounce) || angular.isObject(debounce)) {
$$debounce(function() {
scope.select({activeIdx: activeIdx});
scope.select({activeIdx: activeIdx, evt: evt});
}, angular.isNumber(debounce) ? debounce : debounce['default']);
} else {
scope.select({activeIdx: activeIdx});
scope.select({activeIdx: activeIdx, evt: evt});
}
};
}
Expand Down
2 changes: 1 addition & 1 deletion template/typeahead/typeahead-popup.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<ul class="dropdown-menu" ng-show="isOpen() && !moveInProgress" ng-style="{top: position().top+'px', left: position().left+'px'}" style="display: block;" role="listbox" aria-hidden="{{!isOpen()}}">
<li ng-repeat="match in matches track by $index" ng-class="{active: isActive($index) }" ng-mouseenter="selectActive($index)" ng-click="selectMatch($index)" role="option" id="{{::match.id}}">
<li ng-repeat="match in matches track by $index" ng-class="{active: isActive($index) }" ng-mouseenter="selectActive($index)" ng-click="selectMatch($index, $event)" role="option" id="{{::match.id}}">
<div uib-typeahead-match index="$index" match="match" query="query" template-url="templateUrl"></div>
</li>
</ul>

0 comments on commit 3e876b8

Please sign in to comment.