Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS "Vertical" ng-repeat

Let's say we have an array of people in the JSON format. Each entity has about 100 attributes. The standard approach of using ng-repeat:

...
<tr>
  <th>Attribute1</th>
  <th>Attribute2</th>
  ...
  <th>AttributeN</th>
</tr>
...
<tr ng-repeat="obj in jsonArray">
  <td>{{ obj.attr1 }}</td>
  <td>{{ obj.attr1 }}</td>
  ...
  <td>{{ obj.attrN }}</td>
</tr>

Which produces the following table:

Attribute1 | Attribute2 | ... | AttributeN
------------------------------------------
value1.1   | value1.2   | ... | value1.N
value2.1   | value2.2   | ... | value2.N
...
valueN.1   | valueN.2   | ... | valueN.N

Instead of this, I need:

Attribute1 | value1.1 | value2.1 | ... | valueN.1
Attribute2 | value1.2 | value2.2 | ... | valueN.2
...        | ...      | ...      | ... | ...
AttributeN | value1.N | value2.N | ... | valueN.N

So the question: how do I achieve this?

  • Without manipulation "by hands" (js-jQuery), without leaving angular world - there will be some event handlers & etc.
like image 627
chip Avatar asked Dec 16 '15 09:12

chip


Video Answer


2 Answers

If I understand correctly what you are trying to achieve, then this is how you would do it:

<table>
  <tr ng-repeat="(key, value) in people[0]">
    <th>{{key}}</th>
    <td ng-repeat="person in people">
      {{person[key]}}
    </td>
  </tr>
</table>

Assuming your data is an array of objects with the same properties, you iterate over the first object in the array to get the keys, which would make the vertical table headers.

After that, you iterate over the whole array and simply output the value for the specific key. Here's a fiddle showing the output:

http://jsfiddle.net/andreiho/huL8pvmg/1/

Of course, you'd have to change things around if you want to manually define the names of your headers. This example just takes the keys in your data. You could also manipulate the data before sending it to the view, so you only send the keys you need.

like image 123
andreiho Avatar answered Oct 01 '22 15:10

andreiho


One approach to solve this problem is by restructuring the jsonArray into an indexed object data structure.

DEMO

Javascript

.controller('DemoController', function(Data, $scope) {

  Data.all().then(function(response) {
    $scope.indexedObjects = indexByAttribute(response.data);
  });

  function indexByAttribute(collection) {
    return collection.reduce(function(result, item) {

      angular.forEach(item, function(value, index) {
        result[index] = result[index] || [];
        result[index].push(value);
      });

      return result;
    }, {});
  }

});

HTML

<table>
  <tr ng-repeat="(index, values) in indexedObjects track by index">
    <th>{{ index }}</th>
    <td ng-repeat="value in values track by $index">
      {{ value }}
    </td>
  </tr>
</table>
like image 30
ryeballar Avatar answered Oct 01 '22 13:10

ryeballar