Hoàng Nguyễn
Hoàng Nguyễn

Reputation: 1170

ag-grid on Angular 2 + date filter not working

I follow the documentation of date filtering here: https://www.ag-grid.com/javascript-grid-filter-date/#gsc.tab=0 However, when I try to filter the date, it just does not work. The result after filtering is the same as before, while other columns such as texts and numbers work. The core problem is supposed to be in the Date object inside gridOptions. I format the date display by Angular date pipe as the same format as filtering format of ag-grid, but the actual date data is something like this: "2017-12-19T08:29:19Z". I don't know whether it affects the filtering method.

Versions: Angular 4+, ag-grid 15.0.0, ag-grid-angular 15.0.0

Here is my code:

import { Component, OnInit } from '@angular/core';
import { DatePipe } from '@angular/common';    
import { GridOptions, GridApi } from "ag-grid";    
import { ApiService } from '../../services/api.service/api.service';
import * as Models from '../../models/models';    

@Component({
  selector: 'app-orders',
  templateUrl: './orders.component.html',
  styleUrls: ['./orders.component.scss']
})

export class OrdersComponent implements OnInit {

  gridOptions: GridOptions;

  gridApi: GridApi;
  gridColumnApi;

  rowSelection;

  orders: Models.Order[] = [];

  constructor(
    private apiService: ApiService,
    private modalService: NgbModal,
    private datePipe: DatePipe
  ) {
    this.gridOptions = <GridOptions>{};
    this.gridOptions.enableColResize = true;
    this.gridOptions.enableFilter = true;
    this.gridOptions.floatingFilter = true;
    this.gridOptions.enableSorting = true;

    this.gridOptions.columnDefs = [
      { headerName: 'Numero', field: 'id', valueFormatter: this.renderZeroPadding },
      { headerName: 'Date', field: 'order_date', 
        filter: 'agDateColumnFilter', cellRenderer: this.dateCellRenderer.bind(this), filterParams:{

          // provide comparator function
          comparator: function (filterLocalDateAtMidnight, cellValue) {

              var dateParts  = cellValue.split("/");
              var month = Number(dateParts[2]);
              var day = Number(dateParts[1]) - 1;
              var year = Number(dateParts[0]);
              var cellDate = new Date(month, day, year);

              // Now that both parameters are Date objects, we can compare
              if (cellDate < filterLocalDateAtMidnight) {
                  return -1;
              } else if (cellDate > filterLocalDateAtMidnight) {
                  return 1;
              } else {
                  return 0;
              }
          }
      } },
    ];
    // allow single row selection only
    this.rowSelection = "single";
  }

  ngOnInit() {
    // get orders and set the values to grid
    this.apiService.getOrders()
      .subscribe((orders: Models.Order[]) => {
        this.orders = orders;
        this.gridOptions.api.setRowData(orders);
      })
  }

  onReady(params) {
    this.gridApi = params.api;
    const self = this;
    setTimeout(function () { self.gridApi.sizeColumnsToFit(); }, 1000);
  }

  // modify the date to wanted format
  dateCellRenderer(params: any) {
    return this.datePipe.transform(params.value, 'MM/dd/yyyy');
  }

  // add zeros to beginning to make id 8 characters 
  renderZeroPadding(params: any) {
    let pad = "00000000";
    return (pad + params.value).slice(-pad.length)
  }    
}

Upvotes: 4

Views: 11149

Answers (3)

bl4ckck
bl4ckck

Reputation: 324

Based on shoaib's answer and reference here https://blog.ag-grid.com/valueformatters-part-2/.

when your date format is like this "2017-12-19T08:29:19Z", you have to transform to date object for example "Thursday 24 Jun 2021 00:00:00 GMT+0700 (Western Indonesian Time)" in filterParams->comparator.

Here's the code snippet how to do it with moment js

filterParams={{
  buttons: ["reset"],
  comparator: (filterLocalDateAtMidnight, cellValue) => {
    const cellDate = moment(cellValue).startOf("day").toDate();

    if (filterLocalDateAtMidnight.getTime() == cellDate.getTime()) {
      return 0;
    }

    if (cellDate < filterLocalDateAtMidnight) {
      return -1;
    }

    if (cellDate > filterLocalDateAtMidnight) {
      return 1;
    }
  },
}}

as you noticed, why did I set the time to 0? that's because if your date format has a time like "05:20:27", and then you compare it to filterLocalDateAtMidnight.getTime() which is 0, it won't compare anything. So you have to change the hour to 0.

Upvotes: 0

Sweta
Sweta

Reputation: 1

Add filter: 'agDateColumnFilter'

{
    headerName: Date,
    filter:'agDateColumnFilter',
    valueFormatter: function(params){
       return moment(param.value).format('MM/DD/YYY');
    }
}

Upvotes: 0

Shoaib Chikate
Shoaib Chikate

Reputation: 8975

Try using below comparator:

comparator: function(filterLocalDateAtMidnight, cellValue) {
      //using moment js
      var dateAsString = moment(cellValue).format('DD/MM/YYYY');
      var dateParts = dateAsString.split("/");
      var cellDate = new Date(Number(dateParts[2]), Number(dateParts[1]) - 1, Number(dateParts[0]));

      if (filterLocalDateAtMidnight.getTime() == cellDate.getTime()) {
        return 0
      }

      if (cellDate < filterLocalDateAtMidnight) {
        return -1;
      }

      if (cellDate > filterLocalDateAtMidnight) {
        return 1;
      }
    }

Plunker

Upvotes: 8

Related Questions