Skip to content
This repository was archived by the owner on Oct 2, 2019. It is now read-only.

Commit b4bbadf

Browse files
authored
Merge pull request #1998 from DarkIsDude/master
feat(choices): allow user select group header
2 parents 4150b0a + d0cb84d commit b4bbadf

File tree

4 files changed

+135
-5
lines changed

4 files changed

+135
-5
lines changed

src/common.css

+19
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,15 @@ body > .select2-container.open {
127127
width: 0;
128128
}
129129

130+
.ui-select-container[theme="selectize"] .ui-select-header-group-selectable:hover {
131+
background-color: #f5f5f5;
132+
}
133+
134+
.ui-select-container[theme="selectize"] .ui-select-header-group-selectable {
135+
cursor: pointer;
136+
padding-left: 15px;
137+
}
138+
130139
/* Bootstrap theme */
131140

132141
/* Helper class to show styles when focus */
@@ -253,6 +262,16 @@ body > .ui-select-bootstrap.open {
253262
border-right: 1px solid #428bca;
254263
}
255264

265+
.ui-select-bootstrap .ui-select-header-group-selectable:hover {
266+
background-color: #f5f5f5;
267+
}
268+
269+
.ui-select-bootstrap .ui-select-header-group-selectable {
270+
color: black;
271+
cursor: pointer;
272+
padding: 3px 10px;
273+
}
274+
256275
.ui-select-bootstrap .ui-select-choices-row>span {
257276
cursor: pointer;
258277
display: block;

src/uiSelectController.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,12 @@ uis.controller('uiSelectCtrl',
175175
ctrl.searchInput[0].focus();
176176
};
177177

178-
ctrl.findGroupByName = function(name) {
178+
ctrl.findGroupByName = function(name, noStrict) {
179179
return ctrl.groups && ctrl.groups.filter(function(group) {
180-
return group.name === name;
180+
if (noStrict)
181+
return group.name == name;
182+
else
183+
return group.name === name;
181184
})[0];
182185
};
183186

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
uis.directive('uiSelectHeaderGroupSelectable', ['$timeout', function($timeout) {
2+
return {
3+
restrict: 'EA',
4+
require: ['^uiSelect'],
5+
scope: {
6+
isEnabled: "<?uiSelectHeaderGroupSelectable"
7+
},
8+
link: function ($scope, $element, attrs, select) {
9+
// TODO Why that???
10+
var $select = select[0];
11+
if (angular.isUndefined($scope.isEnabled)) {
12+
$scope.isEnabled = true;
13+
}
14+
15+
function isEnabled() {
16+
return angular.isUndefined($scope.isEnabled) || $scope.isEnabled;
17+
}
18+
19+
function getElements() {
20+
if ($select.multiple && $select.groups) {
21+
return $element.querySelectorAll('.ui-select-choices-group-label');
22+
} else {
23+
console.error('Use uiSelectHeaderGroupSelectable with no multiple uiSelect or without groupBy');
24+
return [];
25+
}
26+
}
27+
28+
function enableClick() {
29+
if (isEnabled()) {
30+
angular.forEach(getElements(), function(e) {
31+
var element = angular.element(e);
32+
33+
// Check the onClick event is not already listen
34+
if (!element.hasClass('ui-select-header-group-selectable')) {
35+
element.addClass('ui-select-header-group-selectable');
36+
37+
element.on('click', function () {
38+
if (isEnabled()) {
39+
var group = $select.findGroupByName(element.text(), true);
40+
41+
angular.forEach(group.items, function(item) {
42+
$timeout(function() {
43+
$select.select(item, false, ' ');
44+
});
45+
});
46+
}
47+
});
48+
}
49+
});
50+
}
51+
}
52+
53+
function disableClick() {
54+
if (!isEnabled()) {
55+
angular.forEach(getElements(), function(e) {
56+
var element = angular.element(e);
57+
element.removeClass('ui-select-header-group-selectable');
58+
element.off('click');
59+
});
60+
}
61+
}
62+
63+
// Watch element to trigger select event
64+
$scope.$watch('isEnabled', function() {
65+
if (!isEnabled()) {
66+
disableClick();
67+
} else {
68+
enableClick();
69+
}
70+
});
71+
72+
$scope.$watch('$select.groups', enableClick);
73+
$scope.$watch(function() {
74+
return $select.selected && $select.selected.length ? $select.selected.length : -1;
75+
}, enableClick);
76+
}
77+
};
78+
}]);

test/select.spec.js

+33-3
Original file line numberDiff line numberDiff line change
@@ -1921,13 +1921,12 @@ describe('ui-select tests', function () {
19211921
if (attrs.removeSelected !== undefined) { attrsHtml += ' remove-selected="' + attrs.removeSelected + '"'; }
19221922
if (attrs.spinnerEnabled !== undefined) { attrsHtml += ' spinner-enabled="' + attrs.spinnerEnabled + '"'; }
19231923
if (attrs.spinnerClass !== undefined) { attrsHtml += ' spinner-class="' + attrs.spinnerClass + '"'; }
1924-
19251924
if (attrs.groupBy !== undefined) { choicesAttrsHtml += ' group-by="' + attrs.groupBy + '"'; }
19261925
if (attrs.uiDisableChoice !== undefined) { choicesAttrsHtml += ' ui-disable-choice="' + attrs.uiDisableChoice + '"'; }
19271926
if (attrs.refresh !== undefined) { choicesAttrsHtml += ' refresh="' + attrs.refresh + '"'; }
19281927
if (attrs.refreshDelay !== undefined) { choicesAttrsHtml += ' refresh-delay="' + attrs.refreshDelay + '"'; }
1929-
19301928
if (attrs.lockChoice !== undefined) { matchesAttrsHtml += ' ui-lock-choice="' + attrs.lockChoice + '"'; }
1929+
if (attrs.uiSelectHeaderGroupSelectable !== undefined) { choicesAttrsHtml += ' ui-select-header-group-selectable="' + attrs.uiSelectHeaderGroupSelectable + '"'; }
19311930
}
19321931

19331932
matchesAttrsHtml += ' placeholder="' + matchesPlaceholder + '"';
@@ -2084,6 +2083,7 @@ describe('ui-select tests', function () {
20842083
expect(containerWidth - newWidth).toBeLessThan(10);
20852084

20862085
});
2086+
20872087
it('should move to last match when pressing BACKSPACE key from search', function () {
20882088

20892089
var el = createUiSelectMultiple();
@@ -2158,7 +2158,6 @@ describe('ui-select tests', function () {
21582158

21592159
});
21602160

2161-
21622161
it('should move to last match when pressing LEFT key from search', function () {
21632162

21642163
var el = createUiSelectMultiple();
@@ -3161,6 +3160,37 @@ describe('ui-select tests', function () {
31613160
expect(el.scope().$select.spinnerClass).toBe('randomclass');
31623161
});
31633162
});
3163+
3164+
describe('uiSelectHeaderGroupSelectable directive', function () {
3165+
it('should have a default value of false', function () {
3166+
var el = createUiSelectMultiple({ groupBy: "'age'", uiSelectHeaderGroupSelectable: true });
3167+
var ctrl = el.scope().$select;
3168+
3169+
showChoicesForSearch(el, '');
3170+
expect(ctrl.multiple).toEqual(true);
3171+
expect(ctrl.groups.length).toEqual(5);
3172+
openDropdown(el);
3173+
3174+
$(el).find('div.ui-select-header-group-selectable').first().click();
3175+
showChoicesForSearch(el, '');
3176+
expect(ctrl.selected.length).toEqual(2);
3177+
});
3178+
3179+
it('should don\'t work with false attribute', function () {
3180+
var el = createUiSelectMultiple({ groupBy: "'age'", uiSelectHeaderGroupSelectable: false });
3181+
var ctrl = el.scope().$select;
3182+
3183+
showChoicesForSearch(el, '');
3184+
expect(ctrl.multiple).toEqual(true);
3185+
expect(ctrl.groups.length).toEqual(5);
3186+
openDropdown(el);
3187+
3188+
$(el).find('div.ui-select-header-group-selectable').first().click();
3189+
showChoicesForSearch(el, '');
3190+
3191+
expect(ctrl.selected.length).toEqual(0);
3192+
});
3193+
});
31643194
});
31653195

31663196
it('should add an id to the search input field', function () {

0 commit comments

Comments
 (0)