2

I am using bootstrap typeahead in my angular project. My requirement was to open the typeahead drop down by pressing down key when user have not entered any text. I have successfully added this functionality by using this link. Here is my demo.

Now down key opens the drop down and hence it lose the default behavior of traversing the drop down (moving down to next option).

index.html

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet" />
    <link href="style.css" rel="stylesheet" />
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.2/angular.js"></script>
    <script src="ui-bootstrap-tpls-0.10.0.js"></script>
    <script src="script.js"></script>
  </head>

  <body>
    <div class="container-fluid" ng-controller="TypeaheadCtrl">
      <input type="text" ng-keydown="show($event)" ng-trim="false" ng-model="selected" empty-typeahead typeahead="state for state in states | filter:$viewValue:stateComparator" class="form-control" />
      <pre ng-show="opened">Model: {{selected | json}}</pre>
    </div>
  </body>

</html>

script.js

(function () {
  var secretEmptyKey = '[$empty$]'

  angular.module('plunker', ['ui.bootstrap'])
    .directive('emptyTypeahead', function () {
      return {
        require: 'ngModel',
        link: function (scope, element, attrs, modelCtrl) {
          // this parser run before typeahead's parser
          modelCtrl.$parsers.unshift(function (inputValue) {
            var value = (inputValue ? inputValue : secretEmptyKey); // replace empty string with secretEmptyKey to bypass typeahead-min-length check
            modelCtrl.$viewValue = value; // this $viewValue must match the inputValue pass to typehead directive
            return value;
          });

          // this parser run after typeahead's parser
          modelCtrl.$parsers.push(function (inputValue) {
            return inputValue === secretEmptyKey ? '' : inputValue; // set the secretEmptyKey back to empty string
          });
        }
      }
    })
    .controller('TypeaheadCtrl', function($scope, $http, $timeout) {
      $scope.selected = undefined;
      $scope.states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Dakota', 'North Carolina', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'];

      $scope.stateComparator = function (state, viewValue) {
        return viewValue === secretEmptyKey || (''+state).toLowerCase().indexOf((''+viewValue).toLowerCase()) > -1;
      };

      $scope.show = function (e) {
        var keyCode = e.keyCode || e.which;
        if (keyCode == 40) { //If it's the down key
            $timeout(function () {
                $(e.target).triggerHandler('input');
            });
        }
    };

    });
}());

Is there any way to open the drop down when clicking first time and then move to next option if clicked again?

Community
  • 1
  • 1
MKB
  • 7,587
  • 9
  • 45
  • 71
  • i recommend to use https://github.com/twitter/typeahead.js instead, it has a open function which you can call from javascript – Marian Ban Nov 06 '14 at 08:52

1 Answers1

1

Finally, I fix the issue by putting an if condition when opening typeahead drop down.

$scope.show = function (e) {
    if($scope.selected === undefined){
      var keyCode = e.keyCode || e.which;
      if (keyCode == 40) { //If it's the down key
        $timeout(function () {
            $(e.target).triggerHandler('input');
        });
     }
   }
};

and giving undefined in $scope.selected if user have not selected any item:

$scope.clearIfEmpty = function () {
    if($scope.selected !== undefined && $scope.selected.length === 0){
      $scope.selected = undefined;  
    }
}

Fix in action

MKB
  • 7,587
  • 9
  • 45
  • 71
  • And scroll bar not moving issue can be fixed by using this link - http://stackoverflow.com/questions/27705490/up-down-arrow-key-issue-with-typeahead-control-angular-bootstrap-ui/27927907#27927907 – MKB Jan 19 '15 at 10:18