Search code examples
angularjsangularjs-ng-repeatngtable

How do i create a table with a variable amount of columns and dynamic titles in Angular? pref using ng-tables


i am trying create a table from a set of data using ng-tables. The data might not be the same every time. For example, i have these data:

var data = [

    {name: "St.Gabriels",        MeaslesCR: 50, ANC: 30, OPD: 20, SCORE: 100},
    {name: "N'Lale",             MeaslesCR: 52, ANC: 33, OPD: 20, SCORE: 90},
    {name: "Centrum Hospital",   MeaslesCR: 20, ANC: 70, OPD: 30, SCORE: 80},
    {name: "Something Hospital", MeaslesCR: 20, ANC: 50, OPD: 30, SCORE: 70},
    {name: "Wohoo Clinic",       MeaslesCR: 50, ANC: 30, OPD: 40, SCORE: 60}];

But i may for example, not have MeaslesCR included.

So how do i create a table without manually creating all the columns with their respective titles?

I tried something like this:

var indicators = [];

//Getting indicator names
angular.forEach(data[0], function(value, key){
    indicators.push(key);
});

$scope.getTitle = function(i){
    return indicators[i];
}

$scope.tableParams = new ngTableParams({
    page: 1,            // show first page
    count: 10          // count per page
}, {
    total: data.length, // length of data
    getData: function($defer, params) {
        // use build-in angular filter
        var orderedData = params.sorting() ?
            $filter('orderBy')(data, params.orderBy()) :
            data;
        $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
    }
});

and

    <table ng-table="tableParams" class="table">
        <tr ng-repeat="user in $data">
            <td data-title="getTitle($index)" sortable="Name">
                {{user.name}} // pref user.getTitle($index)
            </td>
        </tr>
    </table>

The html code obviously only writes one cell, but can i make it write out "$data.length" amount of cells somehow(this case 5)?

With dynamic titles using getTitle($index) or some other better alternative?

Then fill these columns with their respective user.varValue(user.name, user.MeaslesCR ect)?

I am sorry if my questions are a bit confusing, because i think i am a bit confused myself.

Thanks alot.


Solution

  • Took a bit of work, but this is a working plnkr does what I think you're trying to do.

    http://plnkr.co/edit/7SqPoD2u323KKzi0SYpa?p=preview

    enter image description here

    The notSorted function I got from another post discussing how to guarantee order of iteration over an object. Required to make sure the column and headers are in the same order. You can simplify and get rid of that if you don't need column headers.

    And the ng-if is to leave out an extraneous column that I think is also introduced by the notSorted function. Could probably not have that either if you get rid of the headers.

    html:

    <table border=1>
      <thead>
        <tr>
          <th ng-repeat="key in notSorted(cols)" ng-init="value=cols[key]">{{value}}</th>
        </tr>
      </thead>
      <tbody>
        <tr ng-repeat="row in data">
          <td ng-if="!$last" ng-repeat="dat in notSorted(row)" ng-init="value=row[dat]">{{value}}</td>
        </tr>
      </tbody>
    </table>
    

    script:

    var app = angular.module('plunker', []);
    
    app.controller('MainCtrl', function($scope) {
      $scope.name = 'World';
    
      $scope.data = [
        {name: "St.Gabriels",        MeaslesCR: 50, ANC: 30, OPD: 20, SCORE: 100},
        {name: "N'Lale",             MeaslesCR: 52, ANC: 33, OPD: 20, SCORE: 90},
        {name: "Centrum Hospital",   MeaslesCR: 20, ANC: 70, OPD: 30, SCORE: 80},
        {name: "Something Hospital", MeaslesCR: 20, ANC: 50, OPD: 30, SCORE: 70},
        {name: "Wohoo Clinic",       MeaslesCR: 50, ANC: 30, OPD: 40, SCORE: 60}
      ];
    
      $scope.cols = Object.keys($scope.data[0]);
    
      $scope.notSorted = function(obj){
        if (!obj) {
            return [];
        }
        return Object.keys(obj);
    }
    });
    

    The notSorted() function was found here:

    https://groups.google.com/forum/#!topic/angular/N87uqMfwcTs