Angular.js ui-grid自定义日期过滤器

时间:2015-07-23 13:20:44

标签: angularjs angular-ui-grid

我正在使用位于ui-grid.info的角网格ui-grid。

我正在尝试制作一个自定义过滤器,它将使用日期输入控件按日期过滤网格,一个用于小于,一个用于大于。

我似乎能够在columnDefs:{ field: 'mixedDate', cellFilter: 'date', filterHeaderTemplate: '<div>From <input type="date"> to <input type="date"></div>' }中使用它来获取我想要的控件。当将这些东西放在不同的范围内时,我也可以通过设置data-ng-model =“colFilter.term”来进行某种过滤。过滤似乎甚至不等于。

有没有人有这方面的代码可行或可以指向正确的方向?

以下是关于他们自己网站上的主题的一些教程,但我不太确定如何操纵它们以满足我的需要或甚至可能。

4 个答案:

答案 0 :(得分:4)

你是说这样的意思吗?  enter image description here

首先,您应该包含jQuery UI Datepicker

然后你也会为它创建一个指令:

filters:[{ condition: checkStart}, {condition:checkEnd}],filterHeaderTemplate: '<div class="ui-grid-filter-container">from : <input style="display:inline; width:30%"  class="ui-grid-filter-input" date-picker type="text" ng-model="col.filters[0].term"/> to : <input style="display:inline; width:30%" class="ui-grid-filter-input" date-picker type="text" ng-model="col.filters[1].term"/></div>'

在您的columnDefs中,您还需要使用客户过滤器和过滤器标头模板:

function checkStart(term, value, row, column) { term = term.replace(/\\/g,"") var now = moment(value); if(term) { if(moment(term).isAfter(now, 'day')) return false;; } return true; } function checkEnd(term, value, row, column) { term = term.replace(/\\/g,"") var now = moment(value); if(term) { if(moment(term).isBefore(now, 'day')) return false;; } return true; }

假设您正在使用momentjs 过滤器功能如下:

template<typename T>
void foo(T arg)

答案 1 :(得分:3)

如果其他人正在寻找解决方案,我使用带有datepickers的ui-bootstrap模式在网格标题中实现了自定义FROMTO过滤器。 See this plunker for details

回想起来很明显,但是找到解决方案的一个绊网是确保填充网格中日期列的日期值实际上是Date类型。事实证明,将从日期选择器中选择的日期与字符串进行比较将不会让您走得太远。

注意:此解决方案依赖于lodash进行某些数据转换。

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

app.controller('MainCtrl', ['$scope', '$http', 'uiGridConstants', function ($scope, $http, uiGridConstants) {

  $scope.gridOptions = {
    enableFiltering: true,
    onRegisterApi: function(gridApi){
      $scope.gridApi = gridApi;
    },
    columnDefs: [
      {
        field: 'DATE_TIME',
        displayName: 'Date Time',
        enableFiltering: true,
        enableCellEdit: false,
        filterHeaderTemplate: '<div class="ui-grid-filter-container row"><div ng-repeat="colFilter in col.filters" class="col-md-6 col-md-offset-0 col-sm-6 col-sm-offset-0 col-xs-6 col-xs-offset-0"><div custom-grid-date-filter-header></div></div></div>',
        filters: [
          {
            name: 'From',
            condition: uiGridConstants.filter.GREATER_THAN_OR_EQUAL
          },
          {
            name: 'To',
            condition: uiGridConstants.filter.LESS_THAN_OR_EQUAL
          }
        ],
        cellFilter: 'date:"M/d/yyyy h:mm:ss a"',
        width: '40%'
      },
      {
        field: 'QTY',
        displayName: 'Quantity',
        enableCellEdit: false,
        enableFiltering: false
      },
      {
        field: 'UNIT_COST',
        displayName: 'Unit Cost',
        enableCellEdit: false,
        enableFiltering: false
      },
      {
        field: 'TOTAL_COST',
        displayName: 'Total Cost',
        enableCellEdit: false,
        enableFiltering: false
      }
    ]
  };

  // in plnkr, grab the following data from external file
  // $http.get('grid-data.json')
  //    .success(function(data) {
  //    $scope.gridOptions.data = data;
  
  $scope.gridOptions.data = [
    {
      "DATE_TIME": "2015-10-12T10:46:27.000Z",
      "QTY": 3,
      "UNIT_COST": 0.25,
      "TOTAL_COST": 0.75
    },
    {
      "DATE_TIME": "2015-10-18T06:09:27.000Z",
      "QTY": 4,
      "UNIT_COST": 0.25,
      "TOTAL_COST": 1.00
    },
    {
      "DATE_TIME": "2015-10-05T11:57:27.000Z",
      "QTY": 6,
      "UNIT_COST": 0.55,
      "TOTAL_COST": 0.90
    },
    {
      "DATE_TIME": "2015-10-21T03:42:27.000Z",
      "QTY": 8,
      "UNIT_COST": 0.25,
      "TOTAL_COST": 2.00
    },
    {
      "DATE_TIME": "2015-09-29T18:25:27.000Z",
      "QTY": 3,
      "UNIT_COST": 0.45,
      "TOTAL_COST": 1.35
    },
    {
      "DATE_TIME": "2015-09-19T21:13:27.000Z",
      "QTY": 5,
      "UNIT_COST": 0.25,
      "TOTAL_COST": 1.25
    },
    {
      "DATE_TIME": "2015-08-31T15:46:27.000Z",
      "QTY": 7,
      "UNIT_COST": 0.10,
      "TOTAL_COST": 0.70
    },
    {
      "DATE_TIME": "2015-10-12T10:14:27.000Z",
      "QTY": 2,
      "UNIT_COST": 0.65,
      "TOTAL_COST": 1.30
    }
  ];

  // make sure date values are Date objects
  _.forEach($scope.gridOptions.data, function (val) {
    val.DATE_TIME = new Date(val.DATE_TIME);
  });

}])

.controller('gridDatePickerFilterCtrl', ['$scope', '$timeout', '$uibModal', 'uiGridConstants', function( $scope, $timeout, $uibModal, uiGridConstants) {

  $timeout(function() {
    console.log($scope.col); 
    var field = $scope.col.colDef.name;

    var allDates = _.map($scope.col.grid.appScope.gridOptions.data, function(datum) {
      return datum[field];
    });
      
    var minDate = _.min(allDates);
    var maxDate = _.max(allDates);

    $scope.openDatePicker = function(filter) {
      
      var modalInstance = $uibModal.open({
        templateUrl: 'custom-date-filter.html',
        controller: 'customGridDateFilterModalCtrl as custom',
        size: 'md',
        windowClass: 'custom-date-filter-modal',
        resolve: {
          filterName: [function() {
            return filter.name;
          }],
          minDate: [function() {
            return new Date(minDate);
          }],
          maxDate: [function() {
            return new Date(maxDate);
          }],
        }
      });
  
      modalInstance.result.then(function(selectedDate) {
        
        console.log('date', selectedDate);
        $scope.colFilter.listTerm = [];
        
        console.log(typeof selectedDate);
        console.log(selectedDate instanceof Date);
        
        $scope.colFilter.term = selectedDate;
      });
    };
      
  });
  

}])
.controller('customGridDateFilterModalCtrl', ['$scope', '$rootScope', '$log', '$uibModalInstance', 'filterName', 'minDate', 'maxDate', function($scope, $rootScope, $log, $uibModalInstance, filterName, minDate, maxDate) {
  
    var ctrl = this;

    console.log('filter name', filterName);
    console.log('min date', minDate, 'max date', maxDate);
    
    ctrl.title = 'Select Dates ' + filterName + '...';
    ctrl.minDate = minDate;
    ctrl.maxDate = maxDate;
    ctrl.customDateFilterForm;
  
    ctrl.filterDate = (filterName.indexOf('From') !== -1) ? angular.copy(ctrl.minDate) : angular.copy(ctrl.maxDate);
    
    function setDateToStartOfDay(date) {
      return new Date(date.getFullYear(), date.getMonth(), date.getDate());
    }

    function setDateToEndOfDay(date) {
      return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59);
    }

    ctrl.filterDateChanged = function () {
      ctrl.filterDate = (filterName.indexOf('From') !== -1) ? setDateToStartOfDay(ctrl.filterDate) : setDateToEndOfDay(ctrl.filterDate);
      $log.log('new filter date', ctrl.filterDate);
    };
    
    ctrl.setFilterDate = function(date) {
      $uibModalInstance.close(date);
    };

    ctrl.cancelDateFilter = function() {
      $uibModalInstance.dismiss();
    };
  
}])

.directive('customGridDateFilterHeader', function() {
  return {
    template: '<button class="btn btn-default date-time-filter-buttons" style="width:90%;padding:inherit;" ng-click="openDatePicker(colFilter)">{{ colFilter.name }}</button><div role="button" class="ui-grid-filter-button-select cancel-custom-date-range-filter-button ng-scope" ng-click="removeFilter(colFilter, $index)" ng-if="!colFilter.disableCancelFilterButton" ng-disabled="colFilter.term === undefined || colFilter.term === null || colFilter.term === \'\'" ng-show="colFilter.term !== undefined &amp;&amp; colFilter.term != null" tabindex="0" aria-hidden="false" aria-disabled="false" style=""><i class="ui-grid-icon-cancel cancel-custom-date-range-filter" ui-grid-one-bind-aria-label="aria.removeFilter" aria-label="Remove Filter">&nbsp;</i></div>',
    controller: 'gridDatePickerFilterCtrl'
  };
})
;
<!DOCTYPE html>
<html ng-app="app">

  <head>
    <script src="https://cdn.jsdelivr.net/lodash/4.6.1/lodash.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.3.2/ui-bootstrap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.3.2/ui-bootstrap-tpls.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.7/angular-material.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/3.1.1/ui-grid.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/3.1.1/ui-grid.min.css" type="text/css" />
    <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.7/angular-material.min.css" />
    <link data-require="bootstrap-css@*" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
    <script src="script.js"></script>
  </head>

  <body> 
    
    <div ng-controller="MainCtrl">
      <div id="grid1" ui-grid="gridOptions" class="grid"></div>
    </div>
    
    <script type="text/ng-template" id="custom-date-filter.html">
    
      <div class="col-md-12 col-md-offset-0 col-sm-12 col-sm-offset-0 col-xs-12 col-xs-offset-0">
  
        <div class="modal-header">
          <p class="modal-title well custom-date-filter-header">
            <span class="custom-date-filter-title-text">
              {{ custom.title }}
            </span>
          </p>
        </div>
  
        <div class="row modal-body custom-date-filter-container-row">
  
          <form name="custom.customDateFilterForm"
                ng-submit="custom.setFilterDate(custom.filterDate)"
                no-validation>

            <div class="row custom-filter-date-input-row">
            
              <div class="well col-md-8 col-md-offset-2 col-sm-8 col-sm-offset-2 col-xs-10 col-xs-offset-1 custom-date-filter-input">
              
                <uib-datepicker ng-model="custom.filterDate" 
                    min-date="custom.minDate" 
                    max-date="custom.maxDate"
                    ng-change="custom.filterDateChanged()"
                    class="well well-sm">
                </uib-datepicker>

              </div>

            </div>

            <div class="row modal-footer custom-date-filter-submit-buttons-row">

              <div class="custom-date-filter-submit-buttons-div col-lg-8 col-lg-offset-2 col-md-8 col-md-offset-2 col-sm-10 col-sm-offset-1 col-xs-10 col-xs-offset-1">

                <button class="btn btn-success btn-lg custom-date-filter-submit-button"
                        type="submit">
                  Apply
                </button>

                <button type="button"
                        class="btn btn-warning btn-lg custom-date-filter-cancel-button"
                        ng-click="custom.cancelDateFilter()">
                  Cancel
                </button>

              </div>

            </div>

          </form>
  
        </div>
  
      </div>
    
    </script>
  </body>

</html>

答案 2 :(得分:2)

我正在使用angular-ui-grid 3.1.1和angular-ui-bootstrap 1.3.2。

我的解决方案基于ui-grid filter help和Munna S / Bennett Adams的评论。我用较少的代码获得了一个解决方案。

它适用于两个过滤器和一个自定义模板(&#39; ui-grid / custom-ui-grid-filter&#39;)。

  { field: 'DATE_TIME', name: 'Date Time', cellTooltip: true,
    cellFilter: 'date:\'yyyy-MM-dd\'',
    cellTemplate: 'ui-grid/date-cell',
    filterHeaderTemplate: 'ui-grid/custom-ui-grid-filter',
    width: '40%',
    filters: [
        {
          condition: function(term, value, row, column){
                if (!term) return true;
                var valueDate = new Date(value);
                return valueDate >= term;
            },
          placeholder: 'Greater than or equal'
        },
        {
          condition: function(term, value, row, column){
                if (!term) return true;
                var valueDate = new Date(value);
                return valueDate <= term;
            },
          placeholder: 'Less than or equal'
        }
    ],
    headerCellClass: $scope.highlightFilteredHeader }

请记住,在条件函数中,&#39; term&#39;来自DatePicker过滤器,是一个日期。此外,value是一个格式为&#39; yyyy-MM-dd&#39;在我的例子中。

这是我的Plunkr 希望它有所帮助,如果你有任何改进,请告诉我。

答案 3 :(得分:1)

我使用自定义javascript方法完成了它

condition: function(term, value){
    if (!term) return true;
    var valueDate = new Date(value);
    var replaced = term.replace(/\\/g,'');
    var termDate = new Date(replaced);
    return valueDate < termDate;
},
placeholder: 'less than'