PrimeNG DataTable Custom Sorting or filtering (Angular 2)
Solution 1
I solved this issue using moment.js, because it's easier and faster, but always code can be customized a little bit if You want to do it without any frameworks (i hope few more if conditions, and string conversions)
So You have to add moment.js to Your project: a) by adding src link to your main html index file (where is main angular selector, polyfills etc.) from this site https://cdnjs.com/libraries/moment.js/ b) but if it's production i recommend to add it via npm. http://momentjs.com/docs/ here are other possibilities.
Then you must declare moment variable under import statements and above @Component annotation
declare var moment;
then if u already have primeng module added to Your project, in the html file within primeng's p-dataTable tag there is p-column tag and here within this tag we need to add sortable="custom" and (sortFunction)="mysort($event)" like so:
<p-column field="date" header="Data" sortable="custom" (sortFunction)="mysort($event)"></p-column>
Date displayed with p-column tag is in DD.MM.YYYY string format like e.g: 03.01.2017
After that in component where we are fetching and pushing data to array, which is used to display data in a table, in my example named appointments we need to add function named mysort (because we are calling this function in html p-column tag)
mysort(event) {
let comparer = function (a, b): number {
let formatedA = moment(a.date, "DD.MM.YYYY").format('YYYY-MM-DD');
let formatedB = moment(b.date, "DD.MM.YYYY").format('YYYY-MM-DD');
let result: number = -1;
if (moment(formatedB).isBefore(formatedA, 'day')) result = 1;
return result * event.order;
};
this.appointments.sort(comparer);
}
in my example a.date and b.date is a string like "21.12.2016" that we need to format to YYYY-MM-DD. Then we just are comparing dates.
And just it, i checked this code and it works. I hope it will help someone, and excuse me if explanation was written in tutorial style but this is my first answer and i wanted to do it in the right way :)
Solution 2
I solved it the same way as Relis. However, it didn't work until I reassigned the "this.appointments" variable.
mysort(event) {
this.appointments.sort((appointmentA, appointmentB) => {
// Here the property date is a date string with the format 'dd/mm/yyyy'.
// In the constructor of moment(), the second paramater is
// the format of the string you're passing in.
const momentA = moment(appointmentA.date, 'dd/mm/yyyy');
const momentB = moment(appointmentB.date, 'dd/mm/yyyy');
if(momentB.isBefore(momentA)){
result = 1;
}
return result * event.order;
});
// This is the key here.
this.appointments = [...this.appointments];
}
Rohit Sindhu
Updated on June 06, 2022Comments
-
Rohit Sindhu about 2 years
I am facing issue in sorting/Filtering date column in PrimeNg Datatable.As i am displaying date "dd/mm/yyyy" string .
- if is use template to display "dd/mm/yyyy" then filter is not working as filter working on actual data bind which is in date ISO format.
- if convert data to string format from the back end then sort is not correct as it sort on string instead of date.
-
comeback4you almost 7 yearswhat about if time and data both come?
-
comeback4you almost 7 yearsif time and data both compare .format('YYYY-MM-DD HH:mm:ss'); --> (moment(formatedB).isBefore(formatedA)) result = 1; just removed 'day' keyword it will compare date and time both
-
Joe over 5 years@Relis - Can you please post the whole project with simple example (Angular + Node) to see how is all wired together?