角度引导类型的多重选择

时间:2014-10-16 07:55:57

标签: angular-ui-bootstrap

是否可以从angular ui bootstrap typeahead中选择多个值?

http://angular-ui.github.io/bootstrap/#/typeahead

2 个答案:

答案 0 :(得分:1)

嗨,如果不更改代码库可能不会 - 您可以尝试https://github.com/rayshan/ui-multiselect

答案 1 :(得分:0)

我最近有同样的要求,并且能够通过替代弹出模板覆盖内部引导程序实现来解决它。我创建了一个新的指令(multi-select-typeahead)来封装更改。

模板使用ng-init将范围引用(typeahead popup指令)传递给multi-select-typeahead指令。该指令覆盖了父级的范围。 $ scope。在这种情况下,$ parent是bootstrap typeahead指令本身。 custom指令提供了一个select()的新实现,它由angular bootstrap在内部调用。新实现会阻止弹出窗口关闭并从列表中删除所选项目。

我提供的备用弹出窗口几乎与默认的角度bootstrap typeahead模板“uib / template / typeahead / typeahead-popup.html”完全相同。唯一的修改是添加了ng-init,它将其范围传递给multi-select-typeahead指令。

我敢肯定,如果你足够聪明,你可以通过引用呈现角度引导默认模板并注入ng-init部分,删除重复的引导代码。这将使解决方案对未来的角度引导程序更改更具弹性。话虽这么说,解决方案已经非常糟糕,并且在未来的主要版本中容易出现问题。

希望这对某人有用!

angular.module('typeahead.demo', [
    'ngAnimate',
    'ngSanitize',
    'ui.bootstrap'
]);

angular
    .module('typeahead.demo')
    .controller('TypeaheadDemo', TypeaheadDemo);

function TypeaheadDemo($scope) {
    $scope.addItem = addItem;
    $scope.itemApi = itemApi;

    $scope.items = [];

    function addItem(item) {
        $scope.items.push(item);
    }

    function itemApi() {
        return [
            { name: 'apple' },
            { name: 'orange' },
            { name: 'grape' }
        ];
    }
}

angular
    .module('typeahead.demo')
    .directive('multiSelectTypeahead', multiSelectTypeahead);

function multiSelectTypeahead() {
    return {
        templateUrl: 'multi-select-typeahead.html',
        scope: {
            searchApi: '&',
            displayNameField: '@',
            onSelect: '&',
            inputPlaceholder: '@?'
        },
        link: function ($scope) {
            var uibTypeaheadScope;

            $scope.initializeScope = initializeScope;

            $scope.$watch('isOpen', function (newValue) {
                if (!newValue) {
                    $scope.searchTerm = '';
                }
            });

            function initializeScope(typeaheadPopupScope) {
                uibTypeaheadScope = typeaheadPopupScope.$parent;
                uibTypeaheadScope.select = selectItem;
            }

            function selectItem(index, event) {
                var selectedItem = uibTypeaheadScope.matches[index].model;

                event.stopPropagation();
                if (event.type === 'click') {
                    event.target.blur();
                }
                uibTypeaheadScope.matches.splice(index, 1);
                $scope.onSelect({ item: selectedItem });
            }
        }
    };
}
<!doctype html>
<html ng-app="typeahead.demo">
  <head>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.js"></script>
    <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
  </head>
  
  
  <script type="text/ng-template" id="typeahead-search-results.html">
    <ul ng-init="$parent.$parent.initializeScope(this)"
        class="dropdown-menu"
        ng-show="isOpen() && !moveInProgress"
        ng-style="{ top: position().top + 'px', left: position().left + 'px' }"
        role="listbox"
        aria-hidden="{{ !isOpen() }}">
        <li class="uib-typeahead-match"
            ng-repeat="match in matches track by $index"
            ng-class="{ active: isActive($index) }"
            ng-mouseenter="selectActive($index)"
            ng-click="selectMatch($index, $event)"
            role="option"
            id="{{ ::match.id }}">
            <div uib-typeahead-match
                index="$index"
                match="match"
                query="query"
                template-url="templateUrl"></div>
        </li>
    </ul>
  </script>

  <script type="text/ng-template" id="multi-select-typeahead.html">
    <input type="text"
           placeholder="{{::inputPlaceholder}}"
           ng-model="searchTerm"
           ng-model-options="{debounce: 500}"
           uib-typeahead="result as result[displayNameField] for result in searchApi({ searchText: $viewValue })"
           typeahead-is-open="isOpen"
           class="form-control"
           typeahead-popup-template-url="typeahead-search-results.html" />
  </script>
  
  <body>

<div ng-controller="TypeaheadDemo" style="padding-top: 15px;">

    <multi-select-typeahead class="col-xs-6"
                            search-api="itemApi(searchText)"
                            display-name-field="name"
                            on-select="addItem(item)"
                            input-placeholder="Search Items...">
    </multi-select-typeahead>
    <div class="col-xs-6">
        <ul class="list-group">
            <li class="list-group-item" ng-repeat="item in items">
                {{ item.name }}
            </li>
        </ul>
    </div>

</div>

  </body>
</html>