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

add "group filter" feature #840

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions examples/demo-groupfilter.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<!DOCTYPE html>
<html lang="en" ng-app="demo">
<head>
<meta charset="utf-8">
<title>AngularJS ui-select</title>

<!--
IE8 support, see AngularJS Internet Explorer Compatibility http://docs.angularjs.org/guide/ie
For Firefox 3.6, you will also need to include jQuery and ECMAScript 5 shim
-->
<!--[if lt IE 9]>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/es5-shim/2.2.0/es5-shim.js"></script>
<script>
document.createElement('ui-select');
document.createElement('ui-select-match');
document.createElement('ui-select-choices');
</script>
<![endif]-->

<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular-sanitize.js"></script>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.css">

<!-- ui-select files -->
<script src="../dist/select.js"></script>
<link rel="stylesheet" href="../dist/select.css">

<script src="demo.js"></script>

<!-- Select2 theme -->
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/select2/3.4.5/select2.css">

<!--
Selectize theme
Less versions are available at https://github.com/brianreavis/selectize.js/tree/master/dist/less
-->
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.8.5/css/selectize.default.css">
<!-- <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.8.5/css/selectize.bootstrap2.css"> -->
<!-- <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.8.5/css/selectize.bootstrap3.css"> -->

<style>
body {
padding: 15px;
}

.select2 > .select2-choice.ui-select-match {
/* Because of the inclusion of Bootstrap */
height: 29px;
}

.selectize-control > .selectize-dropdown {
top: 36px;
}
</style>
</head>

<body ng-controller="DemoCtrl">
<script src="demo.js"></script>

<button class="btn btn-default btn-xs" ng-click="enable()">Enable ui-select</button>
<button class="btn btn-default btn-xs" ng-click="disable()">Disable ui-select</button>
<button class="btn btn-default btn-xs" ng-click="clear()">Clear ng-model</button>

<h3>Select2 theme</h3>
<p>Selected: {{country.selected}}</p>


<h2> Filter groups by array (group-filter="['Z','B','C']")</h2>
<ui-select ng-model="country.selected" theme="select2" ng-disabled="disabled" style="width: 300px;" title="Choose a country">
<ui-select-match placeholder="Select or search a country in the list...">{{$select.selected.name}}</ui-select-match>
<ui-select-choices group-by="firstLetterGroupFn" group-filter="['Z','B','C']" repeat="country in countries | filter: $select.search">
<span ng-bind-html="country.name | highlight: $select.search"></span>
<small ng-bind-html="country.code | highlight: $select.search"></small>
</ui-select-choices>
</ui-select>

<h2> Filter groups using a function (group-filter="reverseOrderFilterFn")</h2>
<ui-select ng-model="country.selected" theme="select2" ng-disabled="disabled" style="width: 300px;" title="Choose a country">
<ui-select-match placeholder="Select or search a country in the list...">{{$select.selected.name}}</ui-select-match>
<ui-select-choices group-by="firstLetterGroupFn" group-filter="reverseOrderFilterFn" repeat="country in countries | filter: $select.search">
<span ng-bind-html="country.name | highlight: $select.search"></span>
<small ng-bind-html="country.code | highlight: $select.search"></small>
</ui-select-choices>
</ui-select>


</body>
</html>
8 changes: 8 additions & 0 deletions examples/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ app.controller('DemoCtrl', function($scope, $http, $timeout, $interval) {

};

$scope.firstLetterGroupFn = function (item){
return item.name[0];
};

$scope.reverseOrderFilterFn = function(groups) {
return groups.reverse();
};

$scope.personAsync = {selected : "[email protected]"};
$scope.peopleAsync = [];

Expand Down
3 changes: 2 additions & 1 deletion src/uiSelectChoicesDirective.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ uis.directive('uiSelectChoices',

// var repeat = RepeatParser.parse(attrs.repeat);
var groupByExp = attrs.groupBy;
var groupFilterExp = attrs.groupFilter;

$select.parseRepeatAttr(attrs.repeat, groupByExp); //Result ready at $select.parserResult
$select.parseRepeatAttr(attrs.repeat, groupByExp, groupFilterExp); //Result ready at $select.parserResult

$select.disableChoiceExpression = attrs.uiDisableChoice;
$select.onHighlightCallback = attrs.onHighlight;
Expand Down
24 changes: 22 additions & 2 deletions src/uiSelectController.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ uis.controller('uiSelectCtrl',
}
}

function _groupsFilter(groups, groupNames) {
var i, j, result = [];
for(i = 0; i < groupNames.length ;i++){
for(j = 0; j < groups.length ;j++){
if(groups[j].name == [groupNames[i]]){
result.push(groups[j]);
}
}
}
return result;
}

// When the user clicks on ui-select, displays the dropdown list
ctrl.activate = function(initSearchValue, avoidReset) {
if (!ctrl.disabled && !ctrl.open) {
Expand Down Expand Up @@ -90,11 +102,11 @@ uis.controller('uiSelectCtrl',
})[0];
};

ctrl.parseRepeatAttr = function(repeatAttr, groupByExp) {
ctrl.parseRepeatAttr = function(repeatAttr, groupByExp, groupFilterExp) {
function updateGroups(items) {
var groupFn = $scope.$eval(groupByExp);
ctrl.groups = [];
angular.forEach(items, function(item) {
var groupFn = $scope.$eval(groupByExp);
var groupName = angular.isFunction(groupFn) ? groupFn(item) : item[groupFn];
var group = ctrl.findGroupByName(groupName);
if(group) {
Expand All @@ -104,6 +116,14 @@ uis.controller('uiSelectCtrl',
ctrl.groups.push({name: groupName, items: [item]});
}
});
if(groupFilterExp){
var groupFilterFn = $scope.$eval(groupFilterExp);
if( angular.isFunction(groupFilterFn)){
ctrl.groups = groupFilterFn(ctrl.groups);
} else if(angular.isArray(groupFilterFn)){
ctrl.groups = _groupsFilter(ctrl.groups, groupFilterFn);
}
}
ctrl.items = [];
ctrl.groups.forEach(function(group) {
ctrl.items = ctrl.items.concat(group.items);
Expand Down
47 changes: 47 additions & 0 deletions test/select.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ describe('ui-select tests', function() {
return person.age % 2 ? 'even' : 'odd';
};

scope.filterInvertOrder = function(groups) {
return groups.sort(function(groupA, groupB){
return groupA.name.toLocaleLowerCase() < groupB.name.toLocaleLowerCase();
});
};


scope.people = [
{ name: 'Adam', email: '[email protected]', group: 'Foo', age: 12 },
{ name: 'Amalie', email: '[email protected]', group: 'Foo', age: 12 },
Expand Down Expand Up @@ -702,6 +709,46 @@ describe('ui-select tests', function() {
});
});

describe('choices group filter function', function() {
function createUiSelect() {
return compileTemplate('\
<ui-select ng-model="selection.selected"> \
<ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \
<ui-select-choices group-by="\'group\'" group-filter="filterInvertOrder" repeat="person in people | filter: $select.search"> \
<div ng-bind-html="person.name | highlight: $select.search"></div> \
</ui-select-choices> \
</ui-select>'
);
}
it("should sort groups using filter", function () {
var el = createUiSelect();
expect(el.find('.ui-select-choices-group .ui-select-choices-group-label').map(function() {
return this.textContent;
}).toArray()).toEqual(["Foo", "Baz", "bar"]);
});
});

describe('choices group filter array', function() {
function createUiSelect() {
return compileTemplate('\
<ui-select ng-model="selection.selected"> \
<ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \
<ui-select-choices group-by="\'group\'" group-filter="[\'Foo\']" \
repeat="person in people | filter: $select.search"> \
<div ng-bind-html="person.name | highlight: $select.search"></div> \
</ui-select-choices> \
</ui-select>'
);
}
it("should sort groups using filter", function () {
var el = createUiSelect();
expect(el.find('.ui-select-choices-group .ui-select-choices-group-label').map(function() {
return this.textContent;
}).toArray()).toEqual(["Foo"]);
});
});


it('should throw when no ui-select-choices found', function() {
expect(function() {
compileTemplate(
Expand Down