0

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

1
  • Performance advice: the sorted list should be computed at specific moments, i.e. when you change sort function and in a collection watcher against the tasks list. Otherwise, it is sorted at each digest cycle. Commented Apr 25, 2014 at 17:50

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Quick and simple solution. What may be an issue here is that you add a property to each task only for sorting them. If you want to get rid of it later on you would have to remove it again manually. Also if you modify one of the times somewhere else (without data-binding) the timediff property would become incorrect junk left in the object.
0

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>

2 Comments

Both will work, although the downside to using either is that the timediff function is now restricted to getting the task injected instead of just a start and stop time, which makes it slightly less usable elsewhere in the application.
Option 2 addresses that problem where you can tell it which properties to diff. If you mean you always have to submit an object then yes but you can easily extend the function and change the behaviour if 2 params are passed. I just don't like variable assignments inside {{}}. Although it works I think it makes the code harder to read and debug.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.