angular-bootstrap-multiselect icon indicating copy to clipboard operation
angular-bootstrap-multiselect copied to clipboard

reset multiselect after search

Open peppe863 opened this issue 7 years ago • 0 comments

I have fix the problem of reset multiselect after use search filter.

angular-bootstrap-multiselect.js:

(function () { 'use strict';

var multiselect = angular.module('btorfs.multiselect', ['btorfs.multiselect.templates']);

multiselect.getRecursiveProperty = function (object, path) {
    return path.split('.').reduce(function (object, x) {
        if (object) {
            return object[x];
        } else {
            return null;
        }
    }, object)
};

multiselect.directive('multiselect', ['$filter', '$document', '$log', function ($filter, $document, $log) {
    return {
        restrict: 'AE',
        scope: {
            options: '=',
            displayProp: '@',
            idProp: '@',
            searchLimit: '=?',
            selectionLimit: '=?',
            showSelectAll: '=?',
            showUnselectAll: '=?',
            showSearch: '=?',
            searchFilter: '=?',
            disabled: '=?ngDisabled',
            labels: '=?',
            classesBtn: '=?',
            showTooltip: '=?',
            placeholder: '@?',
            opt: '=' 
        },
        require: 'ngModel',
        templateUrl: 'multiselect.html',
        controller: ['$scope', function($scope) {
            if (angular.isUndefined($scope.classesBtn)) {
                $scope.classesBtn = ['btn-block','btn-default'];
            }
        }],
        link: function ($scope, $element, $attrs, $ngModelCtrl) {
            $scope.selectionLimit = $scope.selectionLimit || 0;
            $scope.searchLimit = $scope.searchLimit || 25;

            $scope.searchFilter = '';

            $scope.resolvedOptions = [];
            if (typeof $scope.options !== 'function') {
                $scope.resolvedOptions = $scope.options;
            }

            if (typeof $attrs.disabled != 'undefined') {
                $scope.disabled = true;
            }


            var closeHandler = function (event) {
                if (!$element[0].contains(event.target)) {
                    $scope.$apply(function () {
                        $scope.open = false;
                    });
                }
            };

            $document.on('click', closeHandler);

            var updateSelectionLists = function () {
                if (!$ngModelCtrl.$viewValue) {
                    if ($scope.selectedOptions) {
                        $scope.selectedOptions = [];
                    }
                    $scope.unselectedOptions = $scope.resolvedOptions.slice(); // Take a copy
                } else {
                    $scope.selectedOptions = $scope.resolvedOptions.filter(function (el) {
                        var id = $scope.getId(el);
                        for (var i = 0; i < $ngModelCtrl.$viewValue.length; i++) {
                            var selectedId = $scope.getId($ngModelCtrl.$viewValue[i]);
                            if (id === selectedId) {
                                return true;
                            }
                        }
                        return false;
                    });
                    $scope.unselectedOptions = $scope.resolvedOptions.filter(function (el) {
                        return $scope.selectedOptions.indexOf(el) < 0;
                    });
                }
            };

            $scope.toggleDropdown = function () {
                $scope.open = !$scope.open;
                $scope.resolvedOptions = $scope.options;
                updateSelectionLists();
            };

            $ngModelCtrl.$render = function () {
                updateSelectionLists();
            };

            $ngModelCtrl.$viewChangeListeners.push(function () {
                updateSelectionLists();
            });

            $ngModelCtrl.$isEmpty = function (value) {
                if (value) {
                    return (value.length === 0);
                } else {
                    return true;
                }
            };

            var watcher = $scope.$watch('selectedOptions', function () {
                $ngModelCtrl.$setViewValue(angular.copy($scope.selectedOptions));
            }, true);

            $scope.$on('$destroy', function () {
                $document.off('click', closeHandler);
                if (watcher) {
                    watcher(); // Clean watcher
                }
            });

            $scope.getButtonText = function () {
                if ($scope.selectedOptions && $scope.selectedOptions.length === 1) {
                    return $scope.getDisplay($scope.selectedOptions[0]);
                }
                if ($scope.selectedOptions && $scope.selectedOptions.length > 1) {
                    var totalSelected = angular.isDefined($scope.selectedOptions) ? $scope.selectedOptions.length : 0;
                    if (totalSelected === 0) {
                        return $scope.labels && $scope.labels.select ? $scope.labels.select : ($scope.placeholder || 'Select');
                    } else {
                        return totalSelected + ' ' + ($scope.labels && $scope.labels.itemsSelected ? $scope.labels.itemsSelected : 'selected');
                    }
                } else {
                    return $scope.labels && $scope.labels.select ? $scope.labels.select : ($scope.placeholder || 'Select');
                }
            };

            $scope.selectAll = function () {
                $scope.selectedOptions = $scope.resolvedOptions.slice(); // Take a copy;
                $scope.unselectedOptions = [];
            };

            $scope.unselectAll = function () {
                $scope.selectedOptions = [];
                $scope.unselectedOptions = $scope.resolvedOptions.slice(); // Take a copy;
            };

            $scope.toggleItem = function (item) {
                if (typeof $scope.selectedOptions === 'undefined') {
                    $scope.selectedOptions = [];
                }
                var selectedIndex = $scope.selectedOptions.indexOf(item);
                var currentlySelected = (selectedIndex !== -1);
                if (currentlySelected) {
                    $scope.unselectedOptions.push($scope.selectedOptions[selectedIndex]);
                    $scope.selectedOptions.splice(selectedIndex, 1);
                } else if (!currentlySelected && ($scope.selectionLimit === 0 || $scope.selectedOptions.length < $scope.selectionLimit)) {
                    var unselectedIndex = $scope.unselectedOptions.indexOf(item);
                    $scope.unselectedOptions.splice(unselectedIndex, 1);
                    $scope.selectedOptions.push(item);
                }
            };

            $scope.getId = function (item) {
                if (angular.isString(item)) {
                    return item;
                } else if (angular.isObject(item)) {
                    if ($scope.idProp) {
                        return multiselect.getRecursiveProperty(item, $scope.idProp);
                    } else {
                        $log.error('Multiselect: when using objects as model, a idProp value is mandatory.');
                        return '';
                    }
                } else {
                    return item;
                }
            };

            $scope.getDisplay = function (item) {
                if (angular.isString(item)) {
                    return item;
                } else if (angular.isObject(item)) {
                    if ($scope.displayProp) {
                        return multiselect.getRecursiveProperty(item, $scope.displayProp);
                    } else {
                        $log.error('Multiselect: when using objects as model, a displayProp value is mandatory.');
                        return '';
                    }
                } else {
                    return item;
                }
            };

            $scope.isSelected = function (item) {
                if (!$scope.selectedOptions) {
                    return false;
                }
                var itemId = $scope.getId(item);
                for (var i = 0; i < $scope.selectedOptions.length; i++) {
                    var selectedElement = $scope.selectedOptions[i];
                    if ($scope.getId(selectedElement) === itemId) {
                        return true;
                    }
                }
                return false;
            };

            $scope.updateOptions = function () {
                if (typeof $scope.options === 'function') {
                    $scope.options().then(function (resolvedOptions) {
                        $scope.resolvedOptions = resolvedOptions;
                        updateSelectionLists();
                    });
                }
            };
            
            angular.extend($scope.opt, {
              directiveFunction: function() {
            	  $scope.searchFilter = '';
            	  $scope.search();
              }
            });

            // This search function is optimized to take into account the search limit.
            // Using angular limitTo filter is not efficient for big lists, because it still runs the search for
            // all elements, even if the limit is reached
            $scope.search = function () {
                var counter = 0;
                return function (item) {
                    if (counter > $scope.searchLimit) {
                        return false;
                    }
                    var displayName = $scope.getDisplay(item);
                    if (displayName) {
                        var result = displayName.toLowerCase().indexOf($scope.searchFilter.toLowerCase()) > -1;
                        if (result) {
                            counter++;
                        }
                        return result;
                    }
                }
            };

        }
    };
}]);

}());

angular.module('btorfs.multiselect.templates', ['multiselect.html']);

angular.module("multiselect.html", []).run(["$templateCache", function ($templateCache) { $templateCache.put("multiselect.html", "<div class="btn-group" style="width: 100%">\n" + " <button type="button" class="btn dropdown-toggle" ng-class="classesBtn" ng-click="toggleDropdown()" ng-disabled="disabled" style="white-space: nowrap; overflow-x: hidden; text-overflow: ellipsis;">\n" + " {{getButtonText()}} <span class="caret">\n" + " \n" + " <ul class="dropdown-menu dropdown-menu-form dropdown-menu-form-custom"\n" + " ng-style="{display: open ? 'block' : 'none'}" style="width: 100%; overflow-x: auto">\n" + "\n" + " <li ng-show="showSelectAll">\n" + " <a ng-click="selectAll()" href="">\n" + " <span class="glyphicon glyphicon-ok"> {{labels.selectAll || 'Select All'}}\n" + " \n" + " \n" + " <li ng-show="showUnselectAll">\n" + " <a ng-click="unselectAll()" href="">\n" + " <span class="glyphicon glyphicon-remove"> {{labels.unselectAll || 'Unselect All'}}\n" + " \n" + " \n" + " <li ng-show="(showSelectAll || showUnselectAll)"\n" + " class="divider">\n" + " \n" + "\n" + " <li role="presentation" ng-repeat="option in selectedOptions" class="active">\n" + " <a class="item-selected" href="" title="{{showTooltip ? getDisplay(option) : ''}}" ng-click="toggleItem(option); $event.stopPropagation()" style="overflow-x: hidden;text-overflow: ellipsis">\n" + " <span class="glyphicon glyphicon-remove">\n" + " {{getDisplay(option)}}\n" + " \n" + " \n" + " <li ng-show="selectedOptions.length > 0" class="divider">\n" + "\n" + " <li ng-show="showSearch">\n" + " <div class="dropdown-header">\n" + " <input type="text" class="form-control input-sm" style="width: 100%;"\n" + " ng-model="searchFilter" placeholder="{{labels.search || 'Search...'}}" ng-change="updateOptions()"/>\n" + " \n" + " \n" + "\n" + " <li ng-show="showSearch" class="divider">\n" + " <li role="presentation" ng-repeat="option in unselectedOptions | filter:search() | limitTo: searchLimit"\n" + " ng-if="!isSelected(option)"\n" + " ng-class="{disabled : selectionLimit && selectedOptions.length >= selectionLimit}">\n" + " <a class="item-unselected" href="" title="{{showTooltip ? getDisplay(option) : ''}}" ng-click="toggleItem(option); $event.stopPropagation()" style="overflow-x: hidden;text-overflow: ellipsis">\n" + " {{getDisplay(option)}}\n" + " \n" + " \n" + "\n" + " <li class="divider" ng-show="selectionLimit > 1">\n" + " <li role="presentation" ng-show="selectionLimit > 1">\n" + " {{selectedOptions.length || 0}} / {{selectionLimit}} {{labels.itemsSelected || 'selected'}}\n" + " \n" + "\n" + " \n" + "\n" + ""); }]);

HTML EXAMPLE:

CALL RESET FROM CONTROLLER:

	$scope.dirOptComuni = {};
	$scope.callDirFunc = function(){
		$scope.dirOptComuni.directiveFunction();
	};

peppe863 avatar May 08 '18 09:05 peppe863