Angular JS - Automatically focus input and show typeahead dropdown - ui.bootstrap.typeahead

后端 未结 11 1518
孤街浪徒
孤街浪徒 2020-11-30 03:07

I am using Angular JS - ui.bootstrap.typeahead:

I would like to click a button and focus an input field and automatically show the typeahead suggestion dropdown. I h

相关标签:
11条回答
  • 2020-11-30 03:32

    I wanted something like the OP's description and the only solution I found was to come up with a template that combines the dropdown and typeahead directives - maybe the OP or someone else will find it useful:

    angular.module('app', ['ui.bootstrap'])
    .controller('AppCtrl', function($scope) {
      $scope.model;
      $scope.options = [{label:'Option 1'}, {label:'Option 2'}, {label:'Option 3'}];
      
      $scope.onSelect = function($item, $model, $label) {
        $scope.model = angular.copy($item);
      }
    });
    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet"/>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.12.0/ui-bootstrap-tpls.min.js"></script>
    
    <div ng-app='app' style='padding:10px'>
      <div ng-controller='AppCtrl'>
        <div class='dropdown' dropdown style='width:200px'>
          <!-- This needs UI Bootstrap 0.12 to work -->
          <div class='input-group'>
            <input type='text' class='form-control' ng-model='model.label' typeahead="op.label for op in options | filter:$viewValue | limitTo:8" typeahead-editable='false' />
            <span class='input-group-btn'>
              <button class='btn btn-default dropdown-toggle' dropdown-toggle>
                <span class='caret'></span>
              </button>
            </span>
          </div>
          <ul class="dropdown-menu" role='menu' style='max-height:200px;overflow-y:scroll'>
            <li ng-repeat='op in options'>
              <a href ng-click='onSelect(op)'>{{op.label}}</a>
            </li>
          </ul>
        </div>
      </div>
    </div>

    Of course, you could simplify it to make the options just an array of strings- I made them objects because that was more like what I needed.

    0 讨论(0)
  • 2020-11-30 03:34

    What we'd want is to trigger('input') on the input element when it's focused.

    The correct way to do it in Angular is to do it in a directive.

    angular.module('app')    
    .directive('showList', function() {
       return {
           restrict: 'A',
           link: function(scope, iEle) {
               iEle.focus(function() {
                   iEle.trigger('input');
               });
           }
       };
    });
    

    Use this directive on the typeahead input element -

    <input show-list uib-typeahead="state for state in states | filter:$viewValue" typeahead-min-length="0" class="form-control">
    
    0 讨论(0)
  • 2020-11-30 03:38

    As HarishR mentioned in a comment, there is no built-in support for this feature yet.

    But I just want to try hacking around and here is the result: http://plnkr.co/edit/Qrnat8yTvISuM1qHHDlA?p=preview

    It contains a lot of hacks to make it works:

    1. include jQuery in order to use .trigger(), could be replace with native JS but I'm lazy.
    2. use ng-focus to call .trigger('input') for triggering the typehead popup
    3. use ng-trim="false" to disable input's value auto trimming
    4. a custom empty-typeahead directive that interact with the ngModel's controller for applying the secretEmptyKey logic to bypass typeahead-min-length check:

      .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
            });
          }
        }
      })
      
    5. a custom filter comparator function that always return true (show all results) when one argument is the secretEmptyKey:

      $scope.stateComparator = function (state, viewValue) {
        return viewValue === secretEmptyKey || (''+state).toLowerCase().indexOf((''+viewValue).toLowerCase()) > -1;
      };
      
    6. remove the limitTo filter to show all results

    7. set max-height and overflow css properties to show scrollbar if content is too long

    Done!

    0 讨论(0)
  • 2020-11-30 03:43

    typeahead-min-length="0" does the trick (I am using v0.4.0)

    0 讨论(0)
  • 2020-11-30 03:44

    I wanted the typeahead to open whenever my input element had focus. @yohairosen's solution didn't work for me on the latest version of Angular Bootstrap (Version: 1.0.3). Here's the solution that worked for me. It involved manually invoking the parser attached by ui-bootstrap-typeahead which populates the suggestions:

    angular.module('app')
    .directive('typeaheadFocus', function () {
      return {
          require: 'ngModel',
          link: function (scope, element, attr, ngModel) {
            element.bind('click', function () {
              ngModel.$parsers[0](ngModel.$viewValue);
            });
          }
        };
      };
    });

    This might be buggy because it assumes the parser added by ui-bootstrap-typeahead is the only one.

    0 讨论(0)
  • 2020-11-30 03:47

    I got a working solution by changing some code in ui-bootstrap-tpls-0.10.0.js. So there are no differences in the typeahead html markup.

    You can have a look here at http://plnkr.co/edit/LXHDpL?p=preview.

    To use this fix, use the ui-bootstrap-tpls-0.10.0.js from the Plunk. To see my changes, open ui-bootstrap-tpls-0.10.0.js from the Plunk and search for 'ahneo'.

     1. //minimal no of characters that needs to be entered before typeahead
        kicks-in
        // ahneo :: before
        //var minSearch = originalScope.$eval(attrs.typeaheadMinLength) || 1;
        // ahneo :: after (changed minimal no of characters to 0 by default)
        var minSearch = originalScope.$eval(attrs.typeaheadMinLength) || 0;
     2. // ahneo :: new (set input value to empty string if it contains " " string value)
        if (inputValue === ' ') {
            inputValue = '';
            modelCtrl.$setViewValue('');
        }  
     3. // ahneo :: before
        //if (inputValue && inputValue.length >= minSearch) {
        // ahneo :: after (add new condition to get matches for min search = 0)
        if (minSearch === 0 || inputValue && inputValue.length >= minSearch) {
     4. // ahneo :: new (bind element to focus event to trigger modelCtrl.$parsers.unshift method)
        element.bind('focus', function (evt) {
            if (modelCtrl.$viewValue === '') {
                modelCtrl.$setViewValue(' ');
            }
        });
    

    Hope this helps

    0 讨论(0)
提交回复
热议问题