Using Bootstrap typeahead with Angular

前端 未结 7 1004
生来不讨喜
生来不讨喜 2020-12-23 22:35

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

相关标签:
7条回答
  • 2020-12-23 22:42

    This is based on @zgohr's implementation

    $('#your-input-id-here').change((event)->
      angular.element("#your-input-id-here").scope().$apply((scope)->
        scope.your_ng_model = event.target.value
      )
    )
    
    0 讨论(0)
  • 2020-12-23 22:44

    Here is another method I have used. It is dirty as well. This code can be dropped in your controller.

    $('#id_of_your_typeahead_input').change(function(event){
      $scope.$apply(function(scope){
        scope.your_ng_model = event.target.value;
      });
      $scope.your_ng_click_function();
    });
    
    0 讨论(0)
  • 2020-12-23 22:45

    I would suggest checking out the typeahead directive from the AngularUI/boostrap repository: http://angular-ui.github.com/bootstrap/

    It is native implementation in pure AngularJS so it doesn't require any 3rd party dependencies. On top of this it is very well integrated with the AngularJS ecosystem as it: * uses concise syntax known from the select directive * understands AngularJS promises so results can be fetched dynamically using $http with the minimal effort.

    0 讨论(0)
  • 2020-12-23 22:47

    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 = '<div class="dropdown"><ul class="dropdown-menu" style="display:block;" ng-hide="!ngModel.length || !filitered.length || selected"><li ng-repeat="item in filitered = (typeahead | filter:{name:ngModel} | limitTo:5) track by $index" ng-click="click(item)" style="cursor:pointer" ng-class="{active:$index==active}" ng-mouseenter="mouseenter($index)"><a>{{item.name}}</a></li></ul></div>'
    
                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:

    <input class="form-control" type="text" autocomplete="false" ng-model="input" placeholder="Start typing a country" typeahead="countries" typeahead-callback="callback" />
    
    0 讨论(0)
  • 2020-12-23 22:52

    There is a working native implementation in AngularStrap for Bootstrap3 that leverages ngAnimate from AngularJS v1.2+

    • Demo : http://mgcrea.github.io/angular-strap/##typeaheads

    You may also want to checkout:

    • Source : https://github.com/mgcrea/angular-strap/blob/master/src/typeahead/typeahead.js
    • Plunkr : http://plnkr.co/edit/VB43wxoDBhVyRMnKUHr9?p=preview
    0 讨论(0)
  • 2020-12-23 22:56

    Another alternative

    In HTML

        <form ng-submit="submitRegion()">
            <input type="text" ng-model="currentRegion" id="region-typeahead" data-source="{{ defaultRegions }}"  data-provide="typeahead"/>
            <button type="submit" class="btn">Add</button>
        </form>
    

    In your Controller

        $scope.defaultRegions = ["Afghanistan", "Australia", "Bahrain", "New Zealand" ];
    
        $scope.submitRegion = function(){
            $scope.currentRegion = $('#region-typeahead').val();
            $scope.addRegion(); //your add or click function you defined
            $scope.currentRegion = ''; //clear
        }
    
    0 讨论(0)
提交回复
热议问题