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

后端 未结 11 1519
孤街浪徒
孤街浪徒 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:49

    you can achieve by this code

     $scope.change = function() {
            var e = document.getElementById("test");
            var $e = angular.element(e);
            $e.triggerHandler('focus');
            $e.triggerHandler('input');
        }
    

    change the test to your type-head ID

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

    Now, as I don't have enough reputation to comment, I must write a new answer to warn people about runTarm's answer above. This is a viable solution, but it runs the risk of running into the following error:

    Error: [$rootScope:inprog] $apply already in progress
    

    This seems to be due to ng-focus being a synchronized event (see discussion here). Instead, one can use the ng-click-attribute, and this error doesn't occur.

    Also, I've verified that

    $element.triggerHandler('input');
    

    works just as good as the jQuery-trigger in runTarm's answer.

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

    I got solved this issue through a directive. When you uses this directive, shows the list without some filter then, you type your search to find an element.

    angular.module('myapp')
    .directive('typeaheadLikeSelect', 
    ['$parse',function($parse) {
        return {
            require: 'ngModel',
            link: function (scope, element, attr, ngModel){
    
                var aux_modelValue, aux_viewValue,
                    modelGetter = $parse(attr.ngModel),
                    modelSetter = modelGetter.assign;
    
                var noViewValue = function(){
                  return
                  ngModel.$$lastCommittedViewValue === undefined ||
                  !ngModel.$$lastCommittedViewValue.trim();
                };
    
                var forceEvent = function(){
                  ngModel.$setViewValue();
                  ngModel.$viewValue = ' ';
                  ngModel.$setViewValue(' ');
                  ngModel.$render();
                  scope.$apply();
                  element.val(element.val().trim());
                };
    
                element.on('mousedown', function(e){
                  e.stopPropagation();
                  forceEvent();
                });
    
                element.on('blur', function(e){
                  e.stopPropagation();
                  if(aux_modelValue){
                    modelSetter(scope, aux_modelValue);
                    scope.$apply();
                  }
                });
    
                scope.$watch(function () {
                  return ngModel.$modelValue;
                }, function(newValue, oldValue){
                  if(newValue || (!newValue && !oldValue))
                    aux_modelValue = newValue;
                });
    
            }
        };
    }]);
    

    I leave a view code, to testing the above code.

    <script type="text/ng-template" id="customTemplate.html">
          <a>
              <span ng-bind-html="match.label.description | uibTypeaheadHighlight:query"></span>
          </a>
    </script>
        <div class="form-group has-feedback" ng-class="{'has-success':items.mymodel}">
                <input
                    placeholder="typeahead"
                    ng-model="items.mymodel"
                    uib-typeahead="responses as responses for responses in getResponses($viewValue)"
                    typeahead-template-url="customTemplate.html"
                    typeahead-input-formatter="$model.description"
                    typeahead-loading="loadingResponses"
                    typeahead-no-results="noResponses"
                    typeahead-editable="false"
                    typeahead-on-select="changeItem($item)"
                    class="form-control"
                  required="required"
                  typeahead-like-select>
                  <div ng-show="noResponses">
                    <i class="glyphicon glyphicon-remove"></i> No Results Found
                  </div>
    
                  <span ng-show="!items.mymodel" class="glyphicon glyphicon-search form-control-feedback" aria-hidden="true"></span>
                  <span ng-show="items.mymodel" class="glyphicon glyphicon-ok form-control-feedback" aria-hidden="true"></span>
              </div>
    
    0 讨论(0)
  • 2020-11-30 03:53

    Seems like built-in support for this feature is coming in an upcoming release in the form of typeahead-min-length attribute supporting value of 0.

    It is implemented in this commit in the master branch https://github.com/angular-ui/bootstrap/commit/d859f42cc022a5d8779f1c7b358486bbdd04ed57, but there is no release with this yet and it's not in the 0.14.x branch.

    Hopefully a new release will come quickly so that there is no need for these workarounds anymore.

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

    Updated:

    I added the directive to github for easy updates and access. You can now install it as a dependency through bower.

    Original post:

    I came up with a pretty clean hack that does not require any changes to ui-bootstrap-tpls. The Idea is to use $setViewValue() to trigger the popup with a combination of a special filter comparator function.

    In order to bypass the minLength check, $setViewValue() has to be set to a value longer than 1 so i'm using one space string. The role of the comparator function is to treat one space as a match to all items so they'll all show up when clicking on an empty input.

    I created a simple directive:

    angular.module('app')
    .directive('typeaheadFocus', function () {
      return {
        require: 'ngModel',
        link: function (scope, element, attr, ngModel) {
    
          //trigger the popup on 'click' because 'focus'
          //is also triggered after the item selection
          element.bind('click', function () {
    
            var viewValue = ngModel.$viewValue;
    
            //restore to null value so that the typeahead can detect a change
            if (ngModel.$viewValue == ' ') {
              ngModel.$setViewValue(null);
            }
    
            //force trigger the popup
            ngModel.$setViewValue(' ');
    
            //set the actual value in case there was already a value in the input
            ngModel.$setViewValue(viewValue || ' ');
          });
    
          //compare function that treats the empty space as a match
          scope.emptyOrMatch = function (actual, expected) {
            if (expected == ' ') {
              return true;
            }
            return actual.indexOf(expected) > -1;
          };
        }
      };
    });
    

    Usage:

    <input type="text" ng-model="selected" typeahead="item for item in items | filter:$viewValue:emptyOrMatch | limitTo:8" typeahead-focus >
    
    0 讨论(0)
提交回复
热议问题