l-lin / angular-datatables

DataTables with Angular
https://l-lin.github.io/angular-datatables/
MIT License
1.57k stars 481 forks source link

how to sort column by date #1678

Closed anasahmedtaj closed 1 year ago

anasahmedtaj commented 1 year ago

Hi i want to sort the column 2 by date in dd-mm-yyyy format in angular 12 (typescript)

Here's my html

<table datatable [dtOptions]="dtOptions" class="row-border hover">
            <thead>
                <tr>
                    <th>Sr.</th>
                    <th>Customers</th>
                    <th>Created on</th>
                    <th>Request/min</th>
                    <th>Request/day</th>
                    <th>Per Request URL</th>
                    <th>status</th>
                </tr>
            </thead>
            <tbody>
                <ng-container *ngFor="let items of customerListTabelData; let i = index">
                    <tr (click)="changeRoute(items.name)">
                        <td>{{i+1}}</td>
                        <td>{{items.name}}</td>
                        <td>{{items.createdAt ? items.createdAt : 'N/A'}}</td>
                        <td>{{items.per_min}}</td>
                        <td>{{items.per_day}}</td>
                        <td>{{items.per_req_url}}</td>
                        <td [ngClass]="items.status">{{items.status}}</td>
                    </tr>
                </ng-container>
            </tbody>
</table>

and my typescript

ngOnInit(): void {
    this.dtOptions = {
      pagingType: 'full_numbers',
      language : {
        paginate : {
          first : "First",
          last : "Last",
          next : "&#9654;",
          previous : "&#9664"
        },
        searchPlaceholder: "Search with Customer Name",
      },
      columnDefs: [
        { targets: 2, type: 'date'},
      ]
    };
    this.getCustomers()
  }

but this doesn't seem to work.

mtholen commented 1 year ago

Hi @anasahmedtaj

You can achieve this by extending the DataTables sort methods. See also here: https://datatables.net/manual/plug-ins/sorting#Custom-ascending-/-descending-methods

You can use a similar method for extending the search function.

Please see below my implementation:

export class fnDataTables {
  static extendSortMethods() {
    $.extend($.fn.dataTable.ext.type.order, {
      'fdate-asc': (a: any, b: any) => sortDateTime(a, b, 1),
      'fdate-desc': (a: any, b: any) => sortDateTime(a, b, -1)
    });
  }

function sortDateTime(a: any, b: any, d: number) {
  a = dateFormatter(a, d);
  b = dateFormatter(b, d);
  return a < b ? -d : a > b ? d : 0;
}

function dateFormatter(arg: string | number | Date, d: number): number {
  return (!arg) ? d * Infinity : +new Date(arg);
  // or some other fancy method for returning a number...
}

the dateFormatter function is merely a method to translate the actual cell content to a JS date (or, in actual fact, the integer representing the Date). In the above I have added a simplified version as in my live version I have a more complex solution as it sometimes needs to extract the data from a link. But the essence is the same.

The null check in the dateFormatter is to ensure that cell-values with no date will -always- be sorted as last. This is to prevent getting those null values appearing on the top when sorting ascending

Note that the sortDateTime only returns 1, -1 or 0, you manipulate the sort direction by the input d when the function extension is initiated. (i.e. sortDateTime(a, b, 1), or sortDateTime(a, b, -1),

then import the class in your component or in your app.module if you wish: import { fnDataTables } from 'src/shared/functions/datatables';

and set the relevant columns to use the correct sorting type in your dtOptions: this.dtOptions.columnDefs = [{ targets: [4], type: 'fdate' }];

stale[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] commented 1 year ago

This issue has been closed due to inactivity. Please feel free to re-open the issue to add new inputs.