Zain Zain - 1 month ago 8
AngularJS Question

How to make a 2 dimensional comparison table in Angular JS

I am working on creating a table similar to a multiplication Table: http://www.eco-pros.com/images/ClipArt-Graphics/multiplication-table.gif for some evaluations.

The data will be coming from the API resource through a REST call using Restangular. Here's the code for the controller after the REST call:

getEvaluations.getList("evaluations?searchBy[participant]=880b6fb0-ee34-11e2-a62e-19e0bcac9427").then(function(data){
evals = data["_embedded"]["items"];

for (i = 0; i < evals.length; i++){
allEvals.push({
rating: evals[i].rating,
alternative: evals[i]["_embedded"]["alternative"].name,
criterion: evals[i]["_embedded"]["criterion"].name
});
/* I'm creating an array of objects to parse the data that comes from the
resource because the back-end is a bit messy. */

}
console.log(allEvals);
$scope.evaluations = {
eval: allEvals
};
$scope.projectID = $routeParams["projectID"];
}, function error (err){
alert("Error in fetching resource");
console.log("error");
});


In the view, I've got a table which I have no clue how to fill up.

<table>
<thead>
<tr>
<th></th>
<th data-ng-repeat="alternative in alternatives">{{alternative.name}}</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="criterion in criteria">
<td><b>{{criterion.description}}</b></td>
<td><input type="text" value="{{evaluations.rating}}" /></td>
<td><input type="text" /></td>
<td><input type="text" /></td>
</tr>
</tbody>
</table>


This is the old code for the table where I was using two REST calls to just get the alternative names and the criterion names to populate the table. But I want to be able to use the array of objects I created to populate that instead. And in the input boxes, I want the rating to go there that matches that specific alternative and criterion (so I need something like a conditional statement to check for AA or AB or AC, etc and inject the value for that).

For Example:


A1


C1 5.0


Any tips or help will be appreciated! Thank you. I'm not sure how to make this question clearer since it's so different.

JS fiddle (not working):

http://jsfiddle.net/GkxeP/8/

Answer Source

The final result:

http://jsfiddle.net/yUwXc/1/


I'm a little confused as to what you're trying to do, exactly, but here's what I did to your fiddle:

  1. I changed onLoad to No wrap - in <body>.

  2. You had an angular external resource AND angular in the framework - that was causing issues. So I took out the external resource.

  3. In your controller declared an object on the scope called evaluations that has a property called eval. In your view, though, you try to call rating on evaluations. Your data isn't structured like that. It looks like you want alternatives in the columns and criterion in the rows, so we need to put your data in a format so that it can be indexed in that fashion. It's conventional to have rows of columns, so I will make the data be indexed by criterion and then alternative. To do this I wrote the following:

    $scope.evaluations = {};
    for (var i = 0; i < allEvals.length; i++) {
        if (!$scope.evaluations.hasOwnProperty(allEvals[i].criterion)) {
            $scope.evaluations[allEvals[i].criterion] = {};
        }
    
        $scope.evaluations[allEvals[i].criterion][allEvals[i].alternative] = allEvals[i].rating;
    }
    

And then in your view:

<input id="#{{alternative.id}}" type="text" value="{{evaluations[criterion.name][alternative.name]}}" />

Please let me know if you need any more assistance :)