0

In my controller, I have a data structure:

this.people = [
    {name: person1, spent: [1, 3, 5,...]},
    {name: person2, spent: [4, 57, 3,...]},
    ...
];

I would like to extract that data to a table-like structure in a way, that names are columns and elements of the spent table are rows of the corresponding column (where the column for each person can be of different length):

person1 | person2
1       | 4
3       | 57
5       | 3

Can I do it somehow with AngularJS and ng-repeat? Or in any other way that will not force me to explicitly loop through the elemens of the 'spent' for each person?

gkalpak
  • 47,844
  • 8
  • 105
  • 118
Magda
  • 172
  • 2
  • 10

2 Answers2

1

Construct your array the normal way :

<table>
    <tr ng-repeat="person in people">
        <td>{{person.name}}</td>
        <td ng-repeat="n in person.spent">{{n}}</td>
    </tr>
</table>

And in your css :

tr { display: block; float: left; }
th, td { display: block;}

With your list of people in the controller :

$scope.people = [
    {name: "person1", spent: [1, 3, 5]},
    {name: "person2", spent: [4, 57, 3,12]}
];

This is magic, and comes from here

Community
  • 1
  • 1
yunandtidus
  • 3,847
  • 3
  • 29
  • 42
  • And the content of ? If I put {{n}} there, then I get elements of person.spent in a row for each person, so can you indicate what content it should have to render what I wanted? – Magda Sep 11 '14 at 05:09
  • the CSS is the key to this answer – Claies Sep 11 '14 at 05:45
  • My apologies, wrong copy past. This should be better (Did not work with IE ...) – yunandtidus Sep 11 '14 at 05:45
  • Ok, this solution works, but I have a feeling that it is a bit of a hack that doesn't allow me to go further with playing with the style of the table (e.g. applying bootstrap class table-striped results in a vertical stripe, not a horizontal; also, the columns do not fill up the whole table if I use bootstrap table class)... So I have still doubts about whether it is really the "correct" way to do it. – Magda Sep 11 '14 at 21:23
  • For sure this is a hack, but remember that TR = table row, then expect it to behave as a column is difficult. – yunandtidus Sep 12 '14 at 06:48
1

For a more standard solution, you need to know what is the highest length of spent array.

I propose :

$scope.maxSpent = function(){
    var max = [];
    for (var i in $scope.people){
        var p = $scope.people[i];
        if (p.spent.length > max.length){
            max = p.spent;
        }
    }
    return max;
}

This will be recomputed very often, you may be smarter depending on how you get your people array.

When this is done, you can construct the table you want :

<table>
    <tr>
        <td ng-repeat="person in people">{{person.name}}</td>
    </tr>
    <tr ng-repeat="n in maxSpent()" ng-init="count = $index">
        <td ng-repeat="person in people">{{person.spent[count]}}</td>
    </tr>
</table>

Nota-Bene, in the above solution, you can construct empty TD that will appear on the resulting table, it is up to you not to display them with :

<table>
    <tr>
        <td ng-repeat="person in people">{{person.name}}</td>
    </tr>
    <tr ng-repeat="n in maxSpent()" ng-init="count = $index">
        <td ng-repeat="person in people" ng-if="person.spent[count]">{{person.spent[count]}}</td>
    </tr>
</table>
yunandtidus
  • 3,847
  • 3
  • 29
  • 42