三、UI-Grid Filtering 筛选

原文: 103 Filtering
简单设置
UI-Grid能够行筛选。需要在 grid options中设置enableFiltering标识(默认是关闭状态)。

在 column def中设置enableFiltering :false 可以禁用该列的过滤。参看下面例子中的“company”列。

在 column def中可以通过filter: { term: ‘xxx’ } 设置筛选选项。可以参看下面例子中的 “gender” 列。如果columnDef的filter没有设置筛选选项,那么用户可以通过输入来筛选。可以直接使用grid.column[i].filters[0] 来覆盖修改初始设置。

条件
以上介绍的筛选对象还可以指定条件,该条件将定义如何将行与筛选项匹配的条件。UI-Grid的几个条件由uiGridConstants.filter.*组成。可以参照下面例子中的“email”列。

如果没有设置条件,UI-Gird会根据过滤器字段的内容进行最佳猜测。可以支持通配符(*)!

如果您想创建自己的筛选逻辑,筛选器对象的条件字段也可以是一个可以在每行运行的function方法。代码如下:

function myCustomSorter(searchTerm, cellValue, row, column) {
  // Custom logic that returns true if `row`
  // passes the filter and false if it should
  // be filtered out
  return booleanResult;
}

可以参考下面例子中的“phone”列;自定义筛选条件将确保除数字以外的所有电话号码都与搜索项进行比较。

您还可以选择创建自定义筛选器条件,该条件不需要用户提供筛选条件-例如,可以在代码里面设置匹配的变量。可以通过在filter中设置 noTerm: true,即使没有筛选条件,过滤条件也会执行。

Placeholder
可以通过设置placeholder 属性,在filter的输入框中增加属性 placeholder=”“。可以参考下面例子中”email” 、”age”列。

多重过滤字段
有时,可能需要为单个列提供两个或多个筛选条件。这个可以通过设置过滤器数组而不是过滤器对象来实现。此数组的元素与前面所有示例中的筛选条件对象的内容相同。事实上, filter: { term: ‘xxx’ }和filters: [{ term: ‘xxx’ }] 是同一个 写法。可以参考下面例子中的“age”列。

日期过滤
该示例还包括日期筛选。但是没有专门的日期过滤方法,所以要过滤日期需要自定义方法。

下拉菜单
过滤支持下拉菜单,可以通过设置type: uiGridConstants.filter.SELECT ; selectOptions: [ { value: ‘x’, label: ‘decode of x’ } , …. ]来实现。
如果需要使用本地化的文字,需要在selectOptions之前设置。

取消图标
默认情况下,筛选器在下拉列表旁边显示一个取消x。可以通过设置disableCancelFilterButton: true 不显示这个按钮。

过滤条件的编程设置
设置过滤条件
在下面例子中,我们提供了一个“切换过滤器”按钮,让您打开和关闭过滤窗口。如果过滤窗口不存在,仍要直观显示哪些列被过滤,我们使用了headerCellClass,当列有过滤条件时,该列的标题文字变为蓝色。

cellFilters
默认情况下,过滤后不会应用cellfilters使用格式化的值,它使用原始值的行。在columnDef option中设置filterCellFiltered 后过滤条件会用cellFilters 来格式化值,可以参考下面例子中“Long Date”列。

单过滤器(类似于2 x)
可以参照singlefilter教程。

index.html

<!doctype html>
<html ng-app="app">
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-touch.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-animate.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/csv.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/pdfmake.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/vfs_fonts.js"></script>
    <script src="http://ui-grid.info/release/ui-grid.js"></script>
    <script src="http://ui-grid.info/release/ui-grid.css"></script>
    <script src="app.js"></script>
  </head>
  <body>
    <div ng-controller="MainCtrl">
      You can use asterisks to fuzz-match, i.e. use "*z*" as your filter to show any row where that column contains a "z".
      <br>
      <br>
      <strong>Note:</strong> The third column has the filter input disabled, but actually has a filter set in code that requires every company to have an 'a' in their name.
      <br>
      <br>
      <button id='toggleFiltering' ng-click="toggleFiltering()" class="btn btn-success">Toggle Filtering</button>
      <div id="grid1" ui-grid="gridOptions" class="grid"></div>
    </div>
  </body>
</html>

main.css

.grid {
  width: 650px;
  height: 400px;
}

.header-filtered {
  color: blue;
}

app.js

var app = angular.module('app', ['ngAnimate', 'ngTouch', 'ui.grid']);

app.controller('MainCtrl', ['$scope', '$http', 'uiGridConstants', function ($scope, $http, uiGridConstants) {
  var today = new Date();
  var nextWeek = new Date();
  nextWeek.setDate(nextWeek.getDate() + 7);

  $scope.highlightFilteredHeader = function( row, rowRenderIndex, col, colRenderIndex ) {
    if( col.filters[0].term ){
      return 'header-filtered';
    } else {
      return '';
    }
  };

  $scope.gridOptions = {
    enableFiltering: true,
    onRegisterApi: function(gridApi){
      $scope.gridApi = gridApi;
    },
    columnDefs: [
      // default
      { field: 'name', headerCellClass: $scope.highlightFilteredHeader },
      // pre-populated search field
      { field: 'gender', filter: {
          term: '1',
          type: uiGridConstants.filter.SELECT,
          selectOptions: [ { value: '1', label: 'male' }, { value: '2', label: 'female' }, { value: '3', label: 'unknown'}, { value: '4', label: 'not stated' }, { value: '5', label: 'a really long value that extends things' } ]
        },
        cellFilter: 'mapGender', headerCellClass: $scope.highlightFilteredHeader },
      // no filter input
      { field: 'company', enableFiltering: false, filter: {
        noTerm: true,
        condition: function(searchTerm, cellValue) {
          return cellValue.match(/a/);
        }
      }},
      // specifies one of the built-in conditions
      // and a placeholder for the input
      {
        field: 'email',
        filter: {
          condition: uiGridConstants.filter.ENDS_WITH,
          placeholder: 'ends with'
        }, headerCellClass: $scope.highlightFilteredHeader
      },
      // custom condition function
      {
        field: 'phone',
        filter: {
          condition: function(searchTerm, cellValue) {
            var strippedValue = (cellValue + '').replace(/[^\d]/g, '');
            return strippedValue.indexOf(searchTerm) >= 0;
          }
        }, headerCellClass: $scope.highlightFilteredHeader
      },
      // multiple filters
      { field: 'age', filters: [
        {
          condition: uiGridConstants.filter.GREATER_THAN,
          placeholder: 'greater than'
        },
        {
          condition: uiGridConstants.filter.LESS_THAN,
          placeholder: 'less than'
        }
      ], headerCellClass: $scope.highlightFilteredHeader},
      // date filter
      { field: 'mixedDate', cellFilter: 'date', width: '15%', filter: {
          condition: uiGridConstants.filter.LESS_THAN,
          placeholder: 'less than',
          term: nextWeek
        }, headerCellClass: $scope.highlightFilteredHeader
      },
      { field: 'mixedDate', displayName: "Long Date", cellFilter: 'date:"longDate"', filterCellFiltered:true, width: '15%',
      }
    ]
  };

  $http.get('/data/500_complex.json')
    .success(function(data) {
      $scope.gridOptions.data = data;
      $scope.gridOptions.data[0].age = -5;

      data.forEach( function addDates( row, index ){
        row.mixedDate = new Date();
        row.mixedDate.setDate(today.getDate() + ( index % 14 ) );
        row.gender = row.gender==='male' ? '1' : '2';
      });
    });

  $scope.toggleFiltering = function(){
    $scope.gridOptions.enableFiltering = !$scope.gridOptions.enableFiltering;
    $scope.gridApi.core.notifyDataChange( uiGridConstants.dataChange.COLUMN );
  };
}])
.filter('mapGender', function() {
  var genderHash = {
    1: 'male',
    2: 'female'
  };

  return function(input) {
    if (!input){
      return '';
    } else {
      return genderHash[input];
    }
  };
});

Demo

作者水平有限,不当之处敬请指正。
感谢您的阅读,如果觉得文章对您有帮助,请支持一下。

发表评论

电子邮件地址不会被公开。 必填项已用*标注