Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(typeahead): Adds extra 'traversal' behaviors. #312

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 45 additions & 2 deletions src/typeahead/typeahead.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ angular.module('mm.foundation.typeahead', ['mm.foundation.position', 'mm.foundat

var hasFocus;

// Typed Input (before traversing matches)
var originalText;

//pop-up element used to display matches
var popUpEl = angular.element('<div typeahead-popup></div>');
popUpEl.attr({
Expand Down Expand Up @@ -98,6 +101,7 @@ angular.module('mm.foundation.typeahead', ['mm.foundation.position', 'mm.foundat
};

var getMatchesAsync = function(inputValue) {
originalText = inputValue;

var locals = {$viewValue: inputValue};
isLoadingSetter(originalScope, true);
Expand Down Expand Up @@ -225,6 +229,21 @@ angular.module('mm.foundation.typeahead', ['mm.foundation.position', 'mm.foundat
element[0].focus();
};

// Traverse is similar to select but doesn't reset matches or hit onSelectCallback.
// It's used for arrowing through matches as opposed to clicking, enter, or tabbing on them.
scope.traverse = function(activeIdx) {
//called from within the $digest() cycle
var locals = {};
var model;

locals[parserResult.itemName] = scope.matches[activeIdx].model;
model = parserResult.modelMapper(originalScope, locals);
$setModelValue(originalScope, model);
modelCtrl.$setValidity('editable', true);

element[0].focus();
};

//bind keyboard events: arrows up(38) / down(40), enter(13) and tab(9), esc(27)
element.bind('keydown', function (evt) {

Expand All @@ -241,11 +260,32 @@ angular.module('mm.foundation.typeahead', ['mm.foundation.position', 'mm.foundat
evt.preventDefault();

if (evt.which === 40) {
scope.activeIdx = (scope.activeIdx + 1) % scope.matches.length;
scope.activeIdx = scope.activeIdx + 1 === scope.matches.length ?
-1 : (scope.activeIdx + 1) % scope.matches.length;

if (scope.activeIdx === -1) {
//set original text back to input
element[0].value = originalText;
} else {
scope.$apply(function() {
scope.traverse(scope.activeIdx);
});
}

scope.$digest();

} else if (evt.which === 38) {
scope.activeIdx = (scope.activeIdx > 0 ? scope.activeIdx : scope.matches.length) - 1;
scope.activeIdx = (scope.activeIdx > -1 ? scope.activeIdx : scope.matches.length) - 1;

if (scope.activeIdx === -1) {
//set original text back to input
element[0].value = originalText;
} else {
scope.$apply(function() {
scope.traverse(scope.activeIdx);
});
}

scope.$digest();

} else if (evt.which === 13 || evt.which === 9) {
Expand All @@ -256,6 +296,9 @@ angular.module('mm.foundation.typeahead', ['mm.foundation.position', 'mm.foundat
} else if (evt.which === 27) {
evt.stopPropagation();

//set original text back to input
element[0].value = originalText;

resetMatches();
scope.$digest();
}
Expand Down