The filter module provides components that allow users to select filter criteria. These components create a button to expose filtering options, a modal footer to display buttons that apply and clear filters, and a summary to indicate which filters have been applied.
Filter modal footer
The filter modal footer component wraps the bb-modal-footer
directive to provide filter-specific buttons that apply and clear filters.
bb-filter-modal-footer
— Specifies the buttons to display in the filter modal's footer.bb-filter-modal-apply
— Specifies a function to be called when users click the button to apply filters.bb-filter-modal-clear
— Specifies a function to be called when users click the button to clear filters.
Filter button
The filter button component creates a button that exposes filtering options.
bb-filter-button
— Creates a button that kicks off a function to expose filtering options.bb-filter-button-on-click
— Specifies a function to be called when users click the filter button.bb-filter-button-active
— (Optional.) Specifies whether the filter button should be given active indication. This property should be set when indication of filtering is not visible to the user, such as when a filter summary is not shown. (Default:false
)
Filter summary
The filter summary component indicates which filters have been applied.
bb-filter-summary
— Displays summary items for the filters that users apply.bb-filter-summary-item
— Displays an entry in the summary for a filter that has been applied.bb-filter-summary-item-on-click
— (Optional.) Specifies a function to be called when users click a summary item.bb-filter-summary-item-is-dismissible
— (Optional.) Indicates whether to include close icons on summary items. (Default:true
)bb-filter-summary-item-on-dismiss
— (Optional.) Specifies a function to be called when users click the close icons on summary items.
Demo
{{item.description}}
Markup
<div ng-controller="FilterTestController as filterCtrl">
<div style="padding: 5px;">
<bb-filter-button
bb-filter-button-on-click="filterCtrl.filterButtonClicked()">
</bb-filter-button>
</div>
<bb-filter-summary ng-show="filterCtrl.appliedFilters && filterCtrl.appliedFilters.length > 0">
<bb-filter-summary-item
ng-repeat="item in filterCtrl.appliedFilters"
bb-filter-summary-item-on-click="filterCtrl.filterButtonClicked()"
bb-filter-summary-item-on-dismiss="filterCtrl.onDismiss($index)" >
{{item.label}}
</bb-filter-summary-item>
</bb-filter-summary>
<div>
<bb-repeater bb-repeater-expand-mode="none">
<bb-repeater-item ng-repeat="item in filterCtrl.filteredItems">
<bb-repeater-item-title>
{{item.name}}
</bb-repeater-item-title>
<bb-repeater-item-content>
<div>
{{item.description}}
</div>
</bb-repeater-item-content>
</bb-repeater-item>
</bb-repeater>
</div>
</div>
<script type="text/ng-template" id="demo/filter/filters.html">
<bb-modal>
<div class="modal-form">
<bb-modal-header>Food preferences</bb-modal-header>
<div bb-modal-body>
<form>
<label for="bb-select-type">Fruit type</label>
<select id="bb-select-type" ng-model="modalCtrl.filters.fruitType" class="form-control">
<option value="any">Any fruit</option>
<option value="citrus">Citrus</option>
<option value="berry">Berry</option>
</select>
<label style="margin-top: 15px;">
<input type="checkbox" bb-check ng-model="modalCtrl.filters.hideOrange" />
Hide orange fruits
</label>
</form>
</div>
<bb-filter-modal-footer
bb-filter-modal-apply="modalCtrl.applyFilters()"
bb-filter-modal-clear="modalCtrl.clearAllFilters()">
</bb-filter-modal-footer>
</div>
</bb-modal>
</script>
JavaScript
/*global angular */
(function () {
'use strict';
function FilterModalController($uibModalInstance, existingFilters) {
var self = this;
function clearAllFilters() {
self.filters = {
fruitType: 'any'
};
}
function transformFiltersToArray(filters) {
var result = [];
if (filters.fruitType && filters.fruitType !== 'any') {
result.push({name: 'fruitType', value: filters.fruitType, label: filters.fruitType});
}
if (filters.hideOrange) {
result.push({name: 'hideOrange', value: true, label: 'hide orange fruits'});
}
return result;
}
function transformArrayToFilters(array) {
var i,
filters = {};
for (i = 0; i < array.length; i++) {
if (array[i].name === 'fruitType') {
filters.fruitType = array[i].value;
}
if (array[i].name === 'hideOrange') {
filters.hideOrange = array[i].value;
}
}
return filters;
}
function applyFilters() {
var result = transformFiltersToArray(self.filters);
$uibModalInstance.close(result);
}
if (!existingFilters) {
clearAllFilters();
} else {
self.filters = transformArrayToFilters(existingFilters);
}
if (angular.isUndefined(self.filters.fruitType)) {
self.filters.fruitType = 'any';
}
self.clearAllFilters = clearAllFilters;
self.applyFilters = applyFilters;
}
FilterModalController.$inject = ['$uibModalInstance', 'existingFilters'];
function FilterTestController(bbModal) {
var self = this,
items = [
{
name: 'Orange',
description: 'A round, orange fruit.',
type: 'citrus',
color: 'orange'
},
{
name: 'Mango',
description: 'Delicious in smoothies, but don\'t eat the skin.',
type: 'other',
color: 'orange'
},
{
name: 'Lime',
description: 'A sour, green fruit used in many drinks.',
type: 'citrus',
color: 'green'
},
{
name: 'Strawberry',
description: 'A red fruit that goes well with shortcake.',
type: 'berry',
color: 'red'
},
{
name: 'Blueberry',
description: 'A small, blue fruit often found in muffins.',
type: 'berry',
color: 'blue'
}
];
function orangeFilterFailed(filter, item) {
return filter.name === 'hideOrange' && filter.value && item.color === 'orange';
}
function fruitTypeFilterFailed(filter, item) {
return filter.name === 'fruitType' && filter.value !== 'any' && filter.value !== item.type;
}
function itemIsShown(filters, item) {
var passesFilter = true,
j;
for (j = 0; j < filters.length; j++) {
if (orangeFilterFailed(filters[j], item)) {
passesFilter = false
} else if (fruitTypeFilterFailed(filters[j], item)) {
passesFilter = false
}
}
return passesFilter;
}
function filterItems(items, filters) {
var i,
passesFilter,
result = [];
for (i = 0; i < items.length; i++) {
passesFilter = itemIsShown(filters, items[i]);
if (passesFilter) {
result.push(items[i]);
}
}
return result;
}
self.filteredItems = items;
self.filterButtonClicked = function () {
bbModal
.open({
controller: 'FilterModalController as modalCtrl',
templateUrl: 'demo/filter/filters.html',
resolve: {
existingFilters: function () {
return angular.copy(self.appliedFilters);
}
}
})
.result
.then(function (result) {
self.appliedFilters = angular.copy(result);
self.filteredItems = filterItems(items, self.appliedFilters);
},
angular.noop
);
};
self.onDismiss = function (index) {
self.appliedFilters.splice(index, 1);
self.filteredItems = filterItems(items, self.appliedFilters);
}
}
FilterTestController.$inject = ['bbModal'];
angular
.module('stache')
.controller('FilterTestController', FilterTestController)
.controller('FilterModalController', FilterModalController);
})();