Saturday, October 5, 2013

An Angular Select directive with multiple selection support that works in IE8 or greater, FireFox and Chrome.


Here is an Angular select directive that has multiple selection support and it works in IE 8 or greater, FireFox and Chrome.

directives.directive('multiselect', function () {
    return {
        restrict: 'A',    // Restricted to an attribute
        scope:
            {
                enableAll: '=',
                options: '=', // Two data binding. Value, DisplayValue, selected
                onSelected: '&' // function called onSelected
            },
        template:
        '<div style="display: inline-block;">' +
        '<span ng-click="showOptions=!showOptions" class="ui-dropdownchecklist ui-dropdownchecklist-selector-wrapper ui-widget" style="display: inline-block; cursor: default; overflow: hidden;">' +
        '   <span class="ui-dropdownchecklist-selector ui-state-default" tabindex="0" style="display: block; overflow: hidden; white-space: nowrap;">'+
        '       <span class="ui-dropdownchecklist-text" style="display: block; white-space: nowrap; overflow: hidden;">{{displayItems}}</span>' +

        '   </span>' +
        '</span>' +
        '<div ng-show="showOptions" class="ui-dropdownchecklist ui-dropdownchecklist-dropcontainer-wrapper ui-widget" style="position: absolute; height: 150px; width: auto; min-width: 227px; z-index: 401;">'+
        '   <div class="ui-dropdownchecklist-dropcontainer ui-widget-content" style="overflow-y: auto; height: 150px;">'+
     
        // All
        '       <div ng-show="enableAll" class="ui-dropdownchecklist-item ui-state-default" style="white-space: nowrap;">' +
        '           <input type="checkbox" ng-change="selectAll(allSelected)" class="active" index="0" value="0" ng-model="allSelected"><label class="ui-dropdownchecklist-text" title="All" style="cursor: default;">All</label>' +
        '       </div>' +  

        '       <div ng-repeat="item in options" class="ui-dropdownchecklist-item ui-state-default" style="white-space: nowrap;">' +
        '           <input type="checkbox" ng-model="item.selected" class="active" index="{{$index+1}}" ng-change="itemChecked()" ><label class="ui-dropdownchecklist-text" title="{{item.DisplayName}}" style="cursor: default;">{{item.DisplayName}}</label>' +
        '       </div>'+      
        '   </div>'+  
        ' </div>'+  
        ' </div>',
        controller: ['$scope', function ($scope) {

            $scope.selectAll = function (item) {
                angular.forEach($scope.options, function (value) {
                    value.selected = item;
                });

                $scope.hasChecked = item;
            };

            $scope.itemChecked = function () {
                $scope.allSelected = true;
                $scope.hasChecked = false;

                angular.forEach($scope.options, function (value) {
                    $scope.allSelected = value.selected && $scope.allSelected;
                    $scope.hasChecked = value.selected || $scope.hasChecked;
                });
            };

            $scope.$watch('options', function(options) {

                if (options) {
                    var listItemsChecked = _.filter(options, function (item) {
                        return item.selected;
                    });

                    if (listItemsChecked) {
                        // Create a list of display items
                        var listOfDisplayItems = _.pluck(listItemsChecked, 'DisplayName');
                     
                        $scope.displayItems = listOfDisplayItems.join();
                    }
                }
            },true);
        }
        ]
};
});

The Angular controller to provide supporting array could look like this:

testApp.controller('MulipleSelectTestController', function ($scope) {
 
    $scope.selectListItems = [
        { Value: 1, DisplayName: 'Kansas', selected: true},
        { Value: 2, DisplayName: 'Ohio' },
        { Value: 3, DisplayName: 'New York' },
    ];

Required CSS:

.ui-dropdownchecklist { width: 228px; }
.ui-dropdownchecklist .ui-dropdownchecklist-selector { background: #fff url('../Images/dropdown.png') no-repeat right center; border: 1px solid #ddd; border-right: 0; height: 20px; text-align: left; }
.ui-dropdownchecklist .ui-dropdownchecklist-selector.ui-state-hover, .ui-dropdownchecklist .ui-dropdownchecklist-selector.ui-state-active { background-image: url('../Images/dropdown_hover.png'); border-color: #5794bf; }

.ui-dropdownchecklist-text, .ui-dropdownchecklist-item { font-family: Arial; font-size: 13px; }
.ui-dropdownchecklist-text { font-weight: 400; height: 20px; line-height: 20px; margin-right:18px; padding-left: 4px; }

.ui-dropdownchecklist-dropcontainer-wrapper { width: auto; z-index: 405 !important; }
.ui-dropdownchecklist-dropcontainer { overflow: hidden; }
.ui-dropdownchecklist-group { font-style: italic; font-weight: 700; }
.ui-dropdownchecklist-item.ui-dropdownchecklist-indent { padding-left: 20px; }

.ui-state-default.ui-dropdownchecklist-selector, .ui-state-hover.ui-dropdownchecklist-selector { color: #000; }
.ui-widget-content.ui-dropdownchecklist-dropcontainer { background: #fff; border: 1px solid #999; }
.ui-widget-content .ui-state-default.ui-dropdownchecklist-item { background: #fff; border: 0; color: #000; }
.ui-widget-content .ui-state-hover.ui-dropdownchecklist-item { background: #39f; border: 0; color: #fff; }

No comments:

Post a Comment