Skip to content

Commit 0a27a70

Browse files
committed
Merge pull request #67 from jeff-phillips-18/filter
Add pfSimpleFilter directive with ngDocs/Example and Unit Tests (PF 2.2 Dependent)
2 parents a85186f + 33a78c8 commit 0a27a70

14 files changed

+855
-3
lines changed

Gruntfile.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,11 @@ module.exports = function (grunt) {
158158
src: ['charts/**/*.html'],
159159
dest: 'templates/charts.js'
160160
},
161+
'patternfly.filters': {
162+
cwd: 'src/',
163+
src: ['filters/**/*.html'],
164+
dest: 'templates/filters.js'
165+
},
161166
'patternfly.views': {
162167
cwd: 'src/',
163168
src: ['views/**/*.html'],

bower.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,6 @@
3939
"angular-touch": "1.3.0 - 1.4.*",
4040
"angular-route": "1.3.0 - 1.4.*",
4141
"lodash": "3.x",
42-
"patternfly": "2.1.0"
42+
"patternfly": "2.2.0"
4343
}
4444
}

dist/angular-patternfly.js

Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ angular.module('patternfly.card', []);
1515
*/
1616
angular.module('patternfly.charts', []);
1717

18+
;/**
19+
* @name patternfly card
20+
*
21+
* @description
22+
* Filters module for patternfly.
23+
*
24+
*/
25+
angular.module('patternfly.filters', ['patternfly.select']);
1826
;/**
1927
* @name patternfly.form
2028
*
@@ -31,6 +39,7 @@ angular.module('patternfly.form', []);
3139
angular.module('patternfly', [
3240
'patternfly.autofocus',
3341
'patternfly.card',
42+
'patternfly.filter',
3443
'patternfly.form',
3544
'patternfly.notification',
3645
'patternfly.select',
@@ -1477,6 +1486,283 @@ angular.module('patternfly.charts').directive('pfUtilizationChart',
14771486
};
14781487
}
14791488
);
1489+
;/**
1490+
* @ngdoc directive
1491+
* @name patternfly.fitlers.directive:pfSimpleFilter
1492+
*
1493+
* @description
1494+
* Directive for a simple filter bar
1495+
* <br><br>
1496+
*
1497+
* @param {object} config configuration settings for the filters:<br/>
1498+
* <ul style='list-style-type: none'>
1499+
* <li>.fields - (Array) List of filterable fields containing:
1500+
* <ul style='list-style-type: none'>
1501+
* <li>.id - (String) Optional unique Id for the filter field, useful for comparisons
1502+
* <li>.title - (String) The title to display for the filter field
1503+
* <li>.placeholder - (String) Text to display when no filter value has been entered
1504+
* <li>.filterType - (String) The filter input field type (any html input type, or 'select' for a select box)
1505+
* <li>.filterValues - (Array) List of valid select values used when filterType is 'select'
1506+
* </ul>
1507+
* <li>.appliedFilters - (Array) List of the currently applied filters
1508+
* <li>.resultsCount - (int) The number of results returned after the current applied filters have been applied
1509+
* <li>.onFilterChange - ( function(array of filters) ) Function to call when the applied filters list changes
1510+
* </ul>
1511+
*
1512+
* @example
1513+
<example module="patternfly.filters" deps="patternfly.select">
1514+
<file name="index.html">
1515+
<div ng-controller="ViewCtrl" class="row example-container">
1516+
<div class="col-md-12">
1517+
<div pf-simple-filter id="exampleSimpleFilter" config="filterConfig"></div>
1518+
</div>
1519+
<hr class="col-md-12">
1520+
<div class="col-md-12">
1521+
<label class="events-label">Valid Items: </label>
1522+
</div>
1523+
<div class="col-md-12">
1524+
<div ng-repeat="item in items" class="col-md-12 cfme-row-column">
1525+
<div class="row">
1526+
<div class="col-md-3">
1527+
<span>{{item.name}}</span>
1528+
</div>
1529+
<div class="col-md-7">
1530+
<span>{{item.address}}</span>
1531+
</div>
1532+
<div class="col-md-2">
1533+
<span>{{item.birthMonth}}</span>
1534+
</div>
1535+
</div>
1536+
</div>
1537+
</div>
1538+
</br></br>
1539+
<div class="col-md-12">
1540+
<label class="events-label">Current Filters: </label>
1541+
</div>
1542+
<div class="col-md-12">
1543+
<textarea rows="5" class="col-md-12">{{filtersText}}</textarea>
1544+
</div>
1545+
</div>
1546+
</file>
1547+
1548+
<file name="script.js">
1549+
angular.module('patternfly.filters').controller('ViewCtrl', ['$scope',
1550+
function ($scope) {
1551+
$scope.filtersText = '';
1552+
1553+
$scope.allItems = [
1554+
{
1555+
name: "Fred Flintstone",
1556+
address: "20 Dinosaur Way, Bedrock, Washingstone",
1557+
birthMonth: 'February'
1558+
},
1559+
{
1560+
name: "John Smith",
1561+
address: "415 East Main Street, Norfolk, Virginia",
1562+
birthMonth: 'October'
1563+
},
1564+
{
1565+
name: "Frank Livingston",
1566+
address: "234 Elm Street, Pittsburgh, Pennsylvania",
1567+
birthMonth: 'March'
1568+
},
1569+
{
1570+
name: "Judy Green",
1571+
address: "2 Apple Boulevard, Cincinatti, Ohio",
1572+
birthMonth: 'December'
1573+
},
1574+
{
1575+
name: "Pat Thomas",
1576+
address: "50 Second Street, New York, New York",
1577+
birthMonth: 'February'
1578+
}
1579+
];
1580+
$scope.items = $scope.allItems;
1581+
1582+
var matchesFilter = function (item, filter) {
1583+
var match = true;
1584+
1585+
if (filter.id === 'name') {
1586+
match = item.name.match(filter.value) !== null;
1587+
} else if (filter.id === 'address') {
1588+
match = item.address.match(filter.value) !== null;
1589+
} else if (filter.id === 'birthMonth') {
1590+
match = item.birthMonth === filter.value;
1591+
}
1592+
return match;
1593+
};
1594+
1595+
var matchesFilters = function (item, filters) {
1596+
var matches = true;
1597+
1598+
filters.forEach(function(filter) {
1599+
if (!matchesFilter(item, filter)) {
1600+
matches = false;
1601+
return false;
1602+
}
1603+
});
1604+
return matches;
1605+
};
1606+
1607+
var applyFilters = function (filters) {
1608+
$scope.items = [];
1609+
if (filters && filters.length > 0) {
1610+
$scope.allItems.forEach(function (item) {
1611+
if (matchesFilters(item, filters)) {
1612+
$scope.items.push(item);
1613+
}
1614+
});
1615+
} else {
1616+
$scope.items = $scope.allItems;
1617+
}
1618+
$scope.filterConfig.resultsCount = $scope.items.length;
1619+
};
1620+
1621+
var filterChange = function (filters) {
1622+
$scope.filtersText = "";
1623+
filters.forEach(function (filter) {
1624+
$scope.filtersText += filter.title + " : " + filter.value + "\n";
1625+
});
1626+
applyFilters(filters);
1627+
};
1628+
1629+
$scope.filterConfig = {
1630+
fields: [
1631+
{
1632+
id: 'name',
1633+
title: 'Name',
1634+
placeholder: 'Filter by Name',
1635+
filterType: 'text'
1636+
},
1637+
{
1638+
id: 'address',
1639+
title: 'Address',
1640+
placeholder: 'Filter by Address',
1641+
filterType: 'text'
1642+
},
1643+
{
1644+
id: 'birthMonth',
1645+
title: 'Birth Month',
1646+
placeholder: 'Filter by Birth Month',
1647+
filterType: 'select',
1648+
filterValues: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
1649+
}
1650+
],
1651+
resultsCount: $scope.items.length,
1652+
appliedFilters: [],
1653+
onFilterChange: filterChange
1654+
};
1655+
}
1656+
]);
1657+
</file>
1658+
</example>
1659+
*/
1660+
angular.module('patternfly.filters').directive('pfSimpleFilter',
1661+
["$document", function ($document) {
1662+
'use strict';
1663+
return {
1664+
restrict: 'A',
1665+
scope: {
1666+
config: '='
1667+
},
1668+
transclude: false,
1669+
templateUrl: 'filters/simple-filter.html',
1670+
controller: ["$scope", function ($scope) {
1671+
var defaultConfig = {
1672+
fields: [],
1673+
resultsCount: 0
1674+
};
1675+
1676+
$scope.setupConfig = function () {
1677+
$scope.config = $.extend(true, angular.copy(defaultConfig), $scope.config);
1678+
1679+
if (!$scope.currentField) {
1680+
$scope.currentField = $scope.config.fields[0];
1681+
$scope.config.currentValue = null;
1682+
}
1683+
1684+
if ($scope.config.currentValue === undefined) {
1685+
$scope.config.currentValue = null;
1686+
}
1687+
1688+
if (!$scope.config.appliedFilters) {
1689+
$scope.config.appliedFilters = [];
1690+
}
1691+
};
1692+
1693+
$scope.selectField = function (item) {
1694+
$scope.currentField = item;
1695+
$scope.config.currentValue = null;
1696+
};
1697+
1698+
$scope.selectValue = function (filterValue) {
1699+
$scope.addFilter($scope.currentField, filterValue);
1700+
$scope.config.currentValue = null;
1701+
};
1702+
1703+
$scope.filterExists = function (filter) {
1704+
var found = false;
1705+
$scope.config.appliedFilters.forEach(function (nextFilter) {
1706+
if (nextFilter.title === filter.title && nextFilter.value === filter.value) {
1707+
found = true;
1708+
}
1709+
});
1710+
return found;
1711+
};
1712+
1713+
$scope.addFilter = function (field, value) {
1714+
var newFilter = {
1715+
id: field.id,
1716+
title: field.title,
1717+
value: value
1718+
};
1719+
if (!$scope.filterExists(newFilter)) {
1720+
$scope.config.appliedFilters.push(newFilter);
1721+
1722+
if ($scope.config.onFilterChange) {
1723+
$scope.config.onFilterChange($scope.config.appliedFilters);
1724+
}
1725+
}
1726+
};
1727+
1728+
$scope.onValueKeyPress = function (keyEvent) {
1729+
if (keyEvent.which === 13) {
1730+
$scope.addFilter($scope.currentField, $scope.config.currentValue);
1731+
$scope.config.currentValue = undefined;
1732+
}
1733+
};
1734+
1735+
$scope.clearFilter = function (item) {
1736+
var newFilters = [];
1737+
$scope.config.appliedFilters.forEach(function (filter) {
1738+
if (item.title !== filter.title || item.value !== filter.value) {
1739+
newFilters.push(filter);
1740+
}
1741+
});
1742+
$scope.config.appliedFilters = newFilters;
1743+
1744+
if ($scope.config.onFilterChange) {
1745+
$scope.config.onFilterChange($scope.config.appliedFilters);
1746+
}
1747+
};
1748+
1749+
$scope.clearAllFilters = function () {
1750+
$scope.config.appliedFilters = [];
1751+
1752+
if ($scope.config.onFilterChange) {
1753+
$scope.config.onFilterChange($scope.config.appliedFilters);
1754+
}
1755+
};
1756+
}],
1757+
1758+
link: function (scope, element, attrs) {
1759+
scope.$watch('config', function () {
1760+
scope.setupConfig();
1761+
}, true);
1762+
}
1763+
};
1764+
}]
1765+
);
14801766
;/**
14811767
* @ngdoc directive
14821768
* @name patternfly.form.directive:pfDatepicker
@@ -3178,6 +3464,14 @@ angular.module('patternfly.views').directive('pfDataTiles', [
31783464
"<div class=utilization-chart-pf><h3>{{config.title}}</h3><div class=current-values><h1 class=\"available-count pull-left\"><span>{{currentValue}}</span></h1><div class=\"available-text pull-left\"><div><span>{{currentText}}</span></div><div><span>of {{chartData.total}} {{config.units}}</span></div></div></div><div pf-donut-pct-chart config=donutConfig data=chartData center-label=centerLabel></div><div pf-sparkline-chart config=sparklineConfig chart-data=chartData chart-height=sparklineChartHeight show-x-axis=showSparklineXAxis show-y-axis=showSparklineYAxis></div><span class=\"pull-left legend-text\">{{legendLeftText}}</span> <span class=\"pull-right legend-text\">{{legendRightText}}</span></div>"
31793465
);
31803466

3467+
}]);
3468+
;angular.module('patternfly.filters').run(['$templateCache', function($templateCache) {
3469+
'use strict';
3470+
3471+
$templateCache.put('filters/simple-filter.html',
3472+
"<div class=simple-filter><form><div class=form-group><div class=input-group><div class=input-group-btn><button type=button class=\"btn btn-default dropdown-toggle filter-fields\" data-toggle=dropdown aria-haspopup=true aria-expanded=false>{{currentField.title}} <span class=caret></span></button><ul class=dropdown-menu><li ng-repeat=\"item in config.fields\"><a class=filter-field role=menuitem tabindex=-1 ng-click=selectField(item)>{{item.title}}</a></li></ul></div><input class=form-control type={{currentField.filterType}} ng-model=config.currentValue placeholder={{currentField.placeholder}} ng-keypress=onValueKeyPress($event) ng-if=\"currentField.filterType !== 'select'\"><select pf-select class=\"form-control filter-select\" id=currentValue ng-model=config.currentValue ng-options=\"o as o for o in currentField.filterValues\" ng-if=\"currentField.filterType === 'select'\" ng-change=selectValue(config.currentValue)><option value=\"\">{{currentField.placeholder}}</option></select></div><!-- /input-group --></div></form><div class=\"row toolbar-pf-results\"><div class=col-sm-12><h5>{{config.resultsCount}} Results</h5><p ng-if=\"config.appliedFilters.length > 0\">Active filters:</p><ul class=list-inline><li ng-repeat=\"filter in config.appliedFilters\"><span class=\"active-filter label label-info\">{{filter.title}}: {{filter.value}} <a href=\"\"><span class=\"pficon pficon-close\" ng-click=clearFilter(filter)></span></a></span></li></ul><p><a class=clear-filters ng-click=clearAllFilters() ng-if=\"config.appliedFilters.length > 0\">Clear All Filters</a></p></div><!-- /col --></div><!-- /row --></div>"
3473+
);
3474+
31813475
}]);
31823476
;angular.module('patternfly.form').run(['$templateCache', function($templateCache) {
31833477
'use strict';

dist/angular-patternfly.min.js

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/styles/angular-patternfly.css

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,3 +273,16 @@
273273
color: #333;
274274
margin-left: 10px;
275275
}
276+
277+
.simple-filter a {
278+
cursor: pointer;
279+
}
280+
281+
.filter-select .btn-default {
282+
font-size: 12px;
283+
font-style: italic;
284+
font-weight: 400;
285+
background-color: #ffffff;
286+
background-image: none;
287+
color: #999999;
288+
}

0 commit comments

Comments
 (0)