raphael_turtle
raphael_turtle

Reputation: 7314

Conditionally add table elements in Angularjs

I have some json to render in a table which looks like;

[{"title":"Super Event","date":"Mon 12 June"},
 {"title":"Another Event","date":"Tue 13 June"},
 {"title":"Something Else","date":"Tue 13 June"}]

I wanted to create a table per date consisting of each days events, or one table with a date row followed by the dates events. I had originally coded this in jquery creating the tables first then appending the events to the respective date table. Currently I can only show every date with every event.

<table>
    <tr ng-repeat="event in events"><th>{{event.date}}</th>
    <td>{{event.title}}</td></tr>
  </table>

Is there an easy way to do this in angular, or should this be done with jquery?

edit: the table output I need has to have either a row or header with the date, followed by rows of the event names e.g

Mon 12 June
Super Event

Tue 13 June
Another Event
Something Else

Upvotes: 1

Views: 854

Answers (2)

lucuma
lucuma

Reputation: 18339

There are a few ways to do it. The first is with a filter:

Demo: http://jsfiddle.net/lucuma/DQ8PK/

HTML:

<div ng-app ng-controller="Main">
    <table ng-repeat="event in eventsToFilter() | filter:filterDate">
        <tr><th>{{event.date}}</th></tr>
        <tr ng-repeat="e in events | filter: {date: event.date}">
            <td>{{e.title}} - {{e.date}}</td>
        </tr>
    </table>
</div>

JS:

function Main($scope) {

    $scope.events = [{
        "title": "Super Event",
        "date": "Mon 12 June"
    }, {
        "title": "Another Event",
        "date": "Tue 13 June"
    }, {
        "title": "Something Else",
        "date": "Tue 13 June"
    }];



    var filterDates = [];
    $scope.eventsToFilter = function () {
        filterDates = [];
        return $scope.events;
    }


    $scope.filterDate = function (event) {
        dateIsNew = filterDates.indexOf(event.date) == -1;
        if (dateIsNew) {
            filterDates.push(event.date);
        }
        return dateIsNew;
    }
}

The second can be done like the following where you check the value of event.date and do something conditionally if it has changed. The following question outlines that strategy: Angular ng-repeat with header views

Upvotes: 2

Piran
Piran

Reputation: 7328

How about something like this: http://plnkr.co/edit/3DvokKEvZeHS9gDMectM?p=preview ?

I've created a quick filter to groupBy which creates a key on the value passed in:

ng-repeat="(date,list) in data | groupBy:'date'"

You can add a sort on that if you want.

The code looks like this:

app.filter('groupBy', function(){
  return function(items,by) {
    var out = {};
    for (var i = 0 ; i < items.length ; i++) {
      var o = out[items[i][by]];
      if (!o) {
        out[items[i][by]] = o = [];
      }
      o.push(items[i])
    }
    return out;
  };
})

Hope that helps.

Upvotes: 1

Related Questions