Creating tables with Angular.js

All we need is an easy explanation of the problem, so here it is.

I am trying to create a table with Angular.js which will have cell’s spanning many rows.

Example:

http://jsfiddle.net/famedriver/kDrc6/

Example data

var data = [{Colors: ["red","green","blue"]}]

Expected output

<table>
  <tr>
    <td rowspan="3">Colors</td>
    <td>red</td>
  </tr>
  <tr>
     <td>green</td>
  </tr>
  <tr>
     <td>blue</td>
  </tr>
 </table>

I have it working by using the ng-show directive. But that still renders an extra cell, just hidden. It would be ideal to have the table properly rendered.

ng-switch, as mentioned, won’t work in certain elements with strict parsing (ie: a table which only allows certain tags)

Any advice?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

Normally you could use ng-switch for something like this, which conditionally adds/removes things from the DOM, unlike ng-show/ng-hide which just hide/show things.

But ng-switch doesn’t play nice with tables because it requires an extra element for the switch statement.

Luckily, someone made a directive called ‘if’ which just takes one attribute on an element and conditionally adds/removes it from the DOM. It’s genius :-).

Here’s an example of it (look in the ‘Resources’ panel on the side, I included it from github). http://jsfiddle.net/5zZ7e/.

I also showed how you can make your controllers without global variables in there.

Method 2

Answering question using more recent version of Angular.

As Andrew Joslin wrote, the ng-show hides the element (it applies display: none). ng-switch removes non-matching elements instead of just hiding them. But it also requires extra element for switch-when expression.

Since the last answer, the ng-if has become a part of Angular, you no longer need an external library.

(function(win) {
  angular.module('myApp', [])
    .controller("Tester", function($scope) {
      $scope.data = {
        Colors: ["red", "green", "blue"]
      }
    })
}(window));
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app="myApp">
  <h1>old code converted</h1>
  <p>Just converted to a newer AngularJS.</p>
  <table border="1" ng-controller="Tester">
    <tbody ng-repeat='(what,items) in data'>
      <tr ng-repeat='item in items'>
        <td rowspan="{{items.length}}" ng-show="$first">{{what}}</td>
        <td>{{item}}</td>
      </tr>
    </tbody>
  </table>
  <h1>solution via ng-if</h1>
  <table border="1" ng-controller="Tester">
    <tbody ng-repeat='(what,items) in data'>
      <tr ng-repeat='item in items'>
        <td rowspan="{{items.length}}" ng-if="$first">{{what}}</td>
        <td>{{item}}</td>
      </tr>
    </tbody>
  </table>
</div>

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply