Sisir
Sisir

Reputation: 2816

EmberJS - Sorting data prior to showing

I have a set of json data I get from server, what I need is to sort them before I show to screen.

Data Example:

{
    "statuses": [
        {
            "id": 1,
            "title":"Post title 1",
            "date":"2014-12-20T11:30:48+0000",
            "sticky":true,
            "comments":[]
        },
        {
            "id": 2,
            "title":"Post title 2",
            "date":"2014-12-25T11:30:48+0000",
            "sticky":false,
            "comments":[]
        },
        {
            "id": 3,
            "title":"Post title 3",
            "date":"2014-12-15T11:30:48+0000",
            "sticky":true,
            "comments":[]
        },
        {
            "id": 4,
            "title":"Post title 4",
            "date":"2014-12-10T11:30:48+0000",
            "sticky":false,
            "comments":[]
        }
    ]
}

I need to

  1. Show sticky statuses first sticky: true sort by date descending.
  2. After then show normal statuses sticky: false sort by date descending

So far I was just able to list them in given data order. You can see the example here http://jsfiddle.net/sisir/kqxz71sg/2/

Resolved

Final working version is given in jsfiddle, I am also adding it here in case the jsfiddle link becomes obsolete in future.

HTML

<div id="main"></div>

<script type="text/x-handlebars" data-template-name="index">
    {{input type="text" value=title}}
    <button {{action "addStatus"}}>Submit</button>
    {{#each status in sortedStatuses}}
        <p {{bind-attr class="status.sticky:sticky"}}>{{status.title}}</p>
    {{/each}}
</script>

JS

App = Ember.Application.create({
    rootElement: '#main'
});

App.ApplicationAdapter = DS.FixtureAdapter;

App.Store = DS.Store.extend();

var attr = DS.attr(),
    string = DS.attr('string'),
    boolean = DS.attr('boolean'),
    number = DS.attr('number'),
    hasMany = DS.hasMany(),
    date = DS.attr('date', {
        defaultValue: function() { return new Date(); }
    });

App.Status = DS.Model.extend({
    sticky: boolean,
    title: string,
    date: date,
    comments: attr
});

App.Status.reopenClass({
  FIXTURES: [
            {
                "id": 1,
                "title":"Post title 1",
                "date":"2014-12-20T11:30:48+0000",
                "sticky":true,
                "comments":[]
            },
            {
                "id": 2,
                "title":"Post title 2",
                "date":"2014-12-25T11:30:48+0000",
                "sticky":false,
                "comments":[]
            },
            {
                "id": 3,
                "title":"Post title 3",
                "date":"2014-12-15T11:30:48+0000",
                "sticky":true,
                "comments":[]
            },
            {
                "id": 4,
                "title":"Post title 4",
                "date":"2014-12-10T11:30:48+0000",
                "sticky":false,
                "comments":[]
            }
        ]
});



App.IndexRoute = Ember.Route.extend({
    setupController: function(controller){
        var statuses = this.store.find('status');
        controller.set('statuses', statuses);
    }
});

App.IndexController = Ember.Controller.extend({
  sortedStatuses: function(){
    var statuses = this.get('statuses');
    var stickyStatuses = statuses.filterBy('sticky').sortBy('date').reverse();
    var nonStickyStatuses = statuses.filterBy('sticky', false).sortBy('date').reverse();    
    var sortedStatuses = stickyStatuses;
    sortedStatuses.pushObjects(nonStickyStatuses);
    return sortedStatuses;
  }.property('statuses.@each'),
  actions: {
    addStatus: function(){
       console.log('ok');
        var status = {
            title: this.title,
            date: new Date(),
            sticky: true
        }

        var status = this.store.createRecord('status', status);
        status.save();
    }
  }
});

css

.sticky{
    background: yellow;
}

Upvotes: 1

Views: 164

Answers (1)

Kalman
Kalman

Reputation: 8121

Create a new computed property called sortedStatuses as follows:

App.IndexController = Ember.Controller.extend({
  sortedStatuses: function(){
    var statuses = this.get('statuses');
    var stickyStatuses = statuses.filterBy('sticky').sortBy('date').reverse();
    var nonStickyStatuses = statuses.filterBy('sticky', false).sortBy('date').reverse();    
    var sortedStatuses = stickyStatuses;
    sortedStatuses.pushObjects(nonStickyStatuses);

    return sortedStatuses;
  }.property('statuses.@each')
});

In your template, you can then loop over sortedStatuses

{{#each status in sortedStatuses}}
    <p {{bind-attr class="status.sticky:sticky"}}>{{status.title}}</p>
{{/each}}

Working example here

Upvotes: 4

Related Questions