Angular 6 - PrimeNG - how to sort column by Date?

亡梦爱人 提交于 2021-02-11 12:11:36

问题


I have a code in Angular - PrimeNG and trying to make sorting by date (one of the columns):

<p-table
  [columns]="cols"
  [value]="questions"
  selectionMode="single"
  [(selection)]="selectedQuestion"
  (onRowSelect)="onRowSelect($event)"
  [paginator]="true"
  [rows]="20">

  <ng-template pTemplate="header" let-columns>
    <tr>
      <th *ngFor="let col of columns">
      </th>
    </tr>
  </ng-template>

  <ng-template 
    pTemplate="body" 
    let-rowData 
    let-columns="columns">
    <tr [pSelectableRow]="rowData">
      <td *ngFor="let col of columns">
        {{rowData[col.field]}}
      </td>
    </tr>
  </ng-template>

</p-table>

One of the columns dates are:
6/26/18
7/26/17

How to sort by Date instead of by String?

Thanks.


回答1:


I've added a rule made with MomentJs and it worked fine form me. It resolved my problem when I was trying to sort the columns with any type of data or string.

if (value1 == null && value2 != null) {
    result = -1;
  } else if (value1 != null && value2 == null) {
    result = 1;
  } else if (value1 == null && value2 == null) {
    result = 0;
  } else if (typeof value1 === 'string' && typeof value2 === 'string') {

    let test = value1.substr(2,1)

    let date1 = moment(value1, 'DD-MM-YYYY')
    let date2 = moment(value2, 'DD-MM-YYYY')
    if(test == '-' || test == '/'){
      result = date1.diff(date2, 'days')
    }else{
      result = value1.localeCompare(value2);
    }

  }else {
    result = (value1 < value2) ? -1 : (value1 > value2) ? 1 : 0;
  }



回答2:


HTML:

<p-dataTable
    [value]="table.rows"
    (onSort)="sortColumn($event)">

    <p-column
        *ngFor="let column of table.columns"
        [field]="column.field"
        [header]="column.header"
        sortable="custom"> 
    // All your columns and stuff and your data and all that </p-column>

</p-dataTable>

TS:

// Add this line at the end of your imports, before the @Component annotation:
import * as moment from 'moment';
// If that doesn't work, you may have to add this instead:
const moment = require('moment');

// Then, in your component body add this:

public dateFieldFormat:string = 'MM/DD/YYYY';
public table; //Assuming this is the data you're passing in. Some sort of JSON with an array of rows and an array of columns

isDateColumn(columnTitle: string) {
    for (const row of this.table.rows) {
      const value = row[columnTitle];
      if (!moment(value, this.dateFieldFormat).isValid() && value !== null) {
        return false;
      }
    }
    return true;
}

sortColumn(eventPayload: any): void {
    this.sort(eventPayload);
    this.table.rows = [...this.table.rows];
}

sort(event: any): Array<any> {
    return this.table.rows.sort((item1, item2) => {
      const value1: string = item1[event.field];
      const value2: string = item2[event.field];

      if (value1 === null) {
        return 1;
      }

      if (this.isDateColumn(event.field)) {
        const date1 = moment(value1, this.dateFieldFormat);
        const date2 = moment(value2, this.dateFieldFormat);

        let result: number = -1;
        if (moment(date2).isBefore(date1, 'day')) { result = 1; }

        return result * event.order;
      }

      let result = null;

      if (value1 == null && value2 != null) {
        result = -1;
      } else if (value1 != null && value2 == null) {
        result = 1;
      } else if (value1 == null && value2 == null) {
        result = 0;
      } else if (typeof value1 === 'string' && typeof value2 === 'string') {
        result = value1.localeCompare(value2);
      } else {
        result = (value1 < value2) ? -1 : (value1 > value2) ? 1 : 0;
      }

      return (event.order * result);
    });
}

primeng 4.3.0

Angular 4.3.6

also using MomentJS which is easy to use :)

I created this myself and have used it extensively. What it does, is when you sort the column, it checks to see whether or not the column you're trying to sort ONLY has dates. And if it does, it will use MomentJS to check values based on chronology. Otherwise it will sort alphabetically. The code for sorting alphabetically comes directly from the primeNG source code, so don't worry about it not functioning correctly :)

Also, if you column with dates has some null values in it, those will always be at the bottom, no matter how you sort, up or down.

Thanks also to the lads in this question: PrimeNG DataTable Custom Sorting or filtering (Angular 2) for starting me out.

Hopefully I've made this clear. Let me know how I can improve my answer if it's unclear, or it doesn't work for you.



来源:https://stackoverflow.com/questions/52666869/angular-6-primeng-how-to-sort-column-by-date

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!