mmmm
mmmm

Reputation: 3938

AngularJS sorting by time difference

I want to enable sorting by each of my table fields. I have one column which shows how many minutes it took to work on project, but sorting by this field doesn't work properly.

<table>

   <th ><a href="" ng-click="sortBy='task.company_name'">Company</a></th>
   <th><a href="" ng-click="sortBy='timediff(task.time_start,task.time_stop)'">Time difference</a><th />

   <tr ng-repeat="task in tasks | orderBy:sortBy">
        <td >{[{ task.company_name }]}</td>
        <td >{[{ timediff(task.time_start,task.time_stop) }]}</td>
    </tr>

</table>

timediff function:

$scope.timediff = function(start, end){
    var start = moment(start);
    var end = moment(end);
    var diff = end.diff(start,'minutes',true);
    return (diff/60).toPrecision(3);
};

Plunker: http://plnkr.co/edit/vdkfNkgpdLUp9RgZ1IvO?p=preview

Upvotes: 0

Views: 506

Answers (2)

Marcel Gwerder
Marcel Gwerder

Reputation: 8520

There is a simpler way for the custom function to work. I edited the dataset a bit to make the switch between "Company" and "Time difference" a bit more clear.

Option 1 (DEMO):

If the property names don't change you can do the following :

$scope.timediff = function(task){
    var start = moment(task.time_start);
    var end = moment(task.time_stop);  
    var diff = end.diff(start,'minutes',true);

    return (diff/60).toPrecision(3);
};

And in your html assign the function to your sortBy variable:

<th ><a href="" ng-click="sortBy='company_name'">Company</a></th>
<th><a href="" ng-click="sortBy=timediff">Time difference</a></th>

<tr ng-repeat="task in tasks | orderBy:sortBy">
    <td >{{ task.company_name }}</td>
    <td >{{ timediff(task)}}</td>
</tr>

Angular automatically passes the current item into the function defined in orderBy.

Option 2 (more flexible) (DEMO):

If you want to define the property names on the fly you can return another function:

$scope.timediff = function(name1, name2){
    return function(item) {
        var start = moment(item[name1]);
        var end = moment(item[name2]);
        var diff = end.diff(start,'minutes',true);

        return (diff/60).toPrecision(3);
    }
};

And give it the two property names:

<th ><a href="" ng-click="sortBy='company_name'">Company</a></th>
<th><a href="" ng-click="sortBy=timediff('time_start', 'time_stop')">Time difference</a></th>

<tr ng-repeat="task in tasks | orderBy:sortBy">
    <td >{{ task.company_name }}</td>
    <td >{{ timediff('time_start', 'time_stop')(task)}}</td>
</tr>

Upvotes: 0

jnthnjns
jnthnjns

Reputation: 8925

Simple fix, just need to assign the function to a parameter

<tr>
    <th><a href="" ng-click="sortBy='company_name'">Company</a></th>
    <th><a href="" ng-click="sortBy='timediff'">Time difference</a></th>
</tr>
<tr ng-repeat="task in tasks | orderBy:sortBy">
    <td>{{ task.company_name }}</td>
    <td>{{ task.timediff = timediff(task.time_start,task.time_stop) }}</td>
</tr>

Here is an updated plunker showing this as well as adding a reverse sort.

Upvotes: 2

Related Questions