angularjs-dropdown-multiselect icon indicating copy to clipboard operation
angularjs-dropdown-multiselect copied to clipboard

Check All function selects disabled items

Open revhelix opened this issue 8 years ago • 2 comments

There is an issue with the Check All / Select All function.

		$scope.selectAll = function() {
			var searchResult;
			$scope.deselectAll(true);
			$scope.externalEvents.onSelectAll();

			searchResult = $filter('filter')($scope.options, $scope.getFilter($scope.input.searchFilter));
			angular.forEach(searchResult, function(value) {
				$scope.setSelectedItem(value[$scope.settings.idProp], true, false);
			});
			$scope.externalEvents.onSelectionChanged();
			$scope.selectedGroup = null;
		};

When you disable an item, the select all does not have a check | filter to see if an item has been disabled.

Also, to note, the disabled item doesn't look disabled.

revhelix avatar Apr 27 '17 22:04 revhelix

I ran into the same issue. It looks like no-one's maintaining the project any longer, so this is how I fixed it:

  1. Moved the .onSelectAll() call to after the default processing in the $scope.selectAll function. (see below)
  2. Added a custom onSelectAll handler within my app controller which will unselect any disabled items. (not shown here)
  3. Added the below CSS to my application's stylesheet for visually noting the disabled options. (see below)

Modified onSelectAll()

	$scope.selectAll = function() {
		var searchResult;
		$scope.deselectAll(true);

		searchResult = $filter('filter')($scope.options, $scope.getFilter($scope.input.searchFilter));
		angular.forEach(searchResult, function(value) {
			$scope.setSelectedItem(value[$scope.settings.idProp], true, false);
		});
		$scope.externalEvents.onSelectAll();
		$scope.externalEvents.onSelectionChanged();
		$scope.selectedGroup = null;
	};

CSS Styling

    /* make hover background same as the normal background for disabled */
    .dropdown-menu li > a[disabled].option:hover { 
        background-color: white;
        background-image: none;
    }
    
    /* make option text light grey for disabled */
    .dropdown-menu a[disabled].option {
        color: #b3b1b1;
    }

glogan91 avatar Jan 23 '18 20:01 glogan91

I solved this issue also by modifying the original code.

The main idea was to make it so the "Deselect All" removes all but currently disabled (and selected) options, via the selectedModel.

Then, the "Select All" will also only select options that are NOT disabled. (deselectAll is called from selectAll, so it's important for Deselect All to be handled correctly)

Modified $scope.selectAll

                $scope.selectAll = function() {
                    var searchResult;
                    var filteredResult;
                    $scope.deselectAll(true);
                    $scope.externalEvents.onSelectAll();

                    searchResult = $filter('filter')($scope.options, $scope.getFilter($scope.input.searchFilter));
                    filteredResult = searchResult.filter(function (option) {
                        return !option.disabled;
                    });
                    angular.forEach(filteredResult, function(value) {
                        $scope.setSelectedItem(value[$scope.settings.idProp], true, false);
                    });
                    $scope.externalEvents.onSelectionChanged();
                    $scope.selectedGroup = null;
                };

Modified $scope.deselectAll

                $scope.deselectAll = function(dontSendEvent) {
                    dontSendEvent = dontSendEvent || false;

                    if (!dontSendEvent) {
                        $scope.externalEvents.onDeselectAll();
                    }

                    if ($scope.singleSelection) {
                        if (!$scope.selectedModel.disabled) {
                            clearObject($scope.selectedModel);
                        }
                    } else {
                        $scope.selectedModel = $scope.filterDisabledSelection($scope.selectedModel, $scope.options);
                    }
                    if (!dontSendEvent) {
                        $scope.externalEvents.onSelectionChanged();
                    }
                    $scope.selectedGroup = null;
                };

"Deselect All" references this newly added function: Note: This uses the lodash _.find function doc here. You'll need to refactor this if you don't have lodash.

                $scope.filterDisabledSelection = function (array, options) {
                    return array.filter(function (option) {
                        var id;

                        if ($scope.settings.externalIdProp === '') {
                            id = option[$scope.settings.idProp];
                        } else {
                            id = option[$scope.settings.externalIdProp];
                        }

                        var match = _.find(options, [$scope.settings.idProp, id]);

                        return match && match.disabled;
                    });
                };

Bonus: From a styling point, I made sure that the list items receive the disabled class correctly for the templating:

                if (groups) {
                    template += '<li ng-repeat-start="option in orderedItems | filter:getFilter(input.searchFilter)" ng-show="getPropertyForObject(option, settings.groupBy) !== getPropertyForObject(orderedItems[$index - 1], settings.groupBy)" role="presentation" class="dropdown-header">{{ getGroupLabel(getPropertyForObject(option, settings.groupBy)) }}</li>';
                    template += '<li ng-class="{\'active\': isChecked(getPropertyForObject(option,settings.idProp)) && settings.styleActive && !option.disabled, \'disabled\': option.disabled}" ng-repeat-end role="presentation">';
                } else {
                    template += '<li ng-class="{\'active\': isChecked(getPropertyForObject(option,settings.idProp)) && settings.styleActive && !option.disabled, \'disabled\': option.disabled}" role="presentation" ng-repeat="option in options | filter:getFilter(input.searchFilter)">';
                }

Drumstix42 avatar May 09 '19 21:05 Drumstix42