I am currently developing a web application which uses twitter-bootstrap and Angularjs in good harmony. However, I have problems with the typeahead and using it as a ng-mode
I made this native typeahead implementation relying only on angular (and bootstrap css for the styling), might help anyone looking how to do this.
Demo here: https://jsfiddle.net/bh29tesc/
Angular directive:
angular.module('app').
directive('typeahead', ['$compile', '$timeout', function($compile, $timeout) {
return {
restrict: 'A',
transclude: true,
scope: {
ngModel: '=',
typeahead: '=',
typeaheadCallback: "="
},
link: function(scope, elem, attrs) {
var template = ''
elem.bind('blur', function() {
$timeout(function() {
scope.selected = true
}, 100)
})
elem.bind("keydown", function($event) {
if($event.keyCode == 38 && scope.active > 0) { // arrow up
scope.active--
scope.$digest()
} else if($event.keyCode == 40 && scope.active < scope.filitered.length - 1) { // arrow down
scope.active++
scope.$digest()
} else if($event.keyCode == 13) { // enter
scope.$apply(function() {
scope.click(scope.filitered[scope.active])
})
}
})
scope.click = function(item) {
scope.ngModel = item.name
scope.selected = item
if(scope.typeaheadCallback) {
scope.typeaheadCallback(item)
}
elem[0].blur()
}
scope.mouseenter = function($index) {
scope.active = $index
}
scope.$watch('ngModel', function(input) {
if(scope.selected && scope.selected.name == input) {
return
}
scope.active = 0
scope.selected = false
// if we have an exact match and there is only one item in the list, automatically select it
if(input && scope.filitered.length == 1 && scope.filitered[0].name.toLowerCase() == input.toLowerCase()) {
scope.click(scope.filitered[0])
}
})
elem.after($compile(template)(scope))
}
}
}]);
Usage: