jdoyle0116
jdoyle0116

Reputation: 83

Simple ember table header sort

I have an ember application in which I have a table. I'm trying to do a simple column header sort but can't seem to get it to work or find any decent examples on how to do this. Any assistance would be appreciated.

links.hbs:

<thead>
    <tr>
        <th {{action "sortBy" "linkID"}}>ID</th>
        <th {{action "sortBy" "name"}}>NAME</th>
        <th {{action "sortBy" "description"}}>DESCRIPTION</th>
        <th {{action "sortBy" "url"}}>URL</th>
        <th {{action "sortBy" "effDate"}}>EFFECTIVE DATE</th>
        <th {{action "sortBy" "endDate"}}>END DATE</th>
        <th {{action "sortBy" "secr"}}>SECURITY RESOURCE</th>          
    <tr>
</thead>

links.js (controller):

import Ember from 'ember';

export default Ember.ArrayController.extend({
    actions:{
            sortBy: function(property) {
                alert('Hello');
                this.set('sortProperties', [property]);
                this.set('sortAscending', !this.get('sortAscending'));
            }
    }

});

Upvotes: 2

Views: 3374

Answers (2)

Robert Carter Mills
Robert Carter Mills

Reputation: 793

I put together a simple example for you here: http://jsbin.com/yilucefuwi/1/edit?html,js,output

Hard to tell what you're doing wrong without seeing your tbody and how you are assigning the array controller's content. Are you sure your #each block is iterating through the item controllers and not directly the model?

Upvotes: 0

nem035
nem035

Reputation: 35491

Assuming you are iterating over the model to build the table, the easiest way (with least amount of changes to your code) you could achieve this is just to set the model to arrangedContent each time you sort (when sortedProperties change):

Controller:

export default Ember.ArrayController.extend({
    sortProperties: ['name'],
    sortAscending: false,

    actions:{

        sortBy: function(property) {
            this.set('sortProperties', [property]);
            this.toggleProperty('sortAscending');
            this.set('model', this.get('arrangedContent'));  // set the model to the sorted array
        } 
    }
});

Template:

<table>
    <thead>
        <tr>
            <th {{action "sortBy" "linkID"}}>ID</th>
            <th {{action "sortBy" "name"}}>NAME</th>
            <th {{action "sortBy" "description"}}>DESCRIPTION</th>
            <th {{action "sortBy" "url"}}>URL</th>
            <th {{action "sortBy" "effDate"}}>EFFECTIVE DATE</th>
            <th {{action "sortBy" "endDate"}}>END DATE</th>
            <th {{action "sortBy" "secr"}}>SECURITY RESOURCE</th>
        </tr>
    </thead>
    <tbody>
    {{#each item in model}}
        <tr>
            <td>{{item.linkID}}</td>
            <td>{{item.name}}</td>
            <td>{{item.description}}</td>
            <td>{{item.url}}</td>
            <td>{{item.effDate}}</td>
            <td>{{item.endDate}}</td>
            <td>{{item.secr}}</td>
        </tr>
    {{/each}}
    </tbody>
</table>

Here is a sample

Here is a full demo

If you need a custom comparator function (for example when comparing dates), you can override the sortFunction hook and Ember will automatically call it when comparing elements for sorting. The parameters passed into sortFunction are the property values corresponding to the content of sortProperties.

For example, for array [ {name: "bob"}, {name: "john"} ] :

// ...
sortProperties: ['name'],
sortFunction: function(propA, propB) {
    // propA === "bob"
    // propB === "john"
    if (propA < propB) {  
        return -1;
    }
    if (propA > propB) {  
        return 1;
    }
    return 0; // a must be equal to b
}
// ...

Upvotes: 2

Related Questions