@@ -15,6 +15,14 @@ angular.module('patternfly.card', []);
1515 */
1616angular . 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', []);
3139angular . 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' ;
0 commit comments