user3541485
user3541485

Reputation:

AngularJS : ng-repeat with uniques values in particular method

I have one object like this

$scope.listvalues = [{ name:A, id:101 },

                     { name:B, id:102 },

                     { name:A, id:103 },

                     { name:C, id:101 },

                     { name:A, id:102 },

                     { name:B, id:103 }];

I need to print this object in following structure

name |101 | 102 |103 |
-----|----|-----|---------
 A   |YES | YES |YES |
-----|----|-----|------------
 B   |No  | YES |YES |
-----|----|-----|-----------
 C   |YES |  NO |NO  |

Here i need to print the Name "A" in unique and also need to indicate the A is available for which Id. Is it possible to do with angularjs ng-repeat?. Any one please suggest...

Upvotes: 3

Views: 83

Answers (3)

dfsq
dfsq

Reputation: 193261

With your array structure you might need some additional helper array/objects. In your case it could look like this:

<table class="table table-bordered">
    <thead>
        <tr>
            <th>Name</th>
            <th ng-repeat="th in values">{{th}}</th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="obj in names">
            <td>
                {{obj.name}}
                <div><small>{{obj}}</small></div>
            </td>
            <td>{{obj.ids.indexOf(values[0]) > -1 ? 'YES' : 'NO'}}</td>
            <td>{{obj.ids.indexOf(values[1]) > -1 ? 'YES' : 'NO'}}</td>
            <td>{{obj.ids.indexOf(values[2]) > -1 ? 'YES' : 'NO'}}</td>
        </tr>
    </tbody>
</table>

where helper objects are constructed like:

function initData() {

    var map = {values: {}, names: {}},
        values = [],
        names = [];

    $scope.listvalues.forEach(function(obj) {
        if (!map.values[obj.id]) {
            values.push(obj.id);
            map.values[obj.id] = true;
        }

        if (!map.names[obj.name]) {
            names.push(obj);
            obj.ids = [obj.id];
            map.names[obj.name] = obj;
        }
        else {
            map.names[obj.name].ids.push(obj.id);
        }
    });

    $scope.values = values;
    $scope.names = names;
}

initData();

Demo: http://plnkr.co/edit/wWJOjtzstUDKjl9V6hCy?p=preview

Upvotes: 0

Blaise
Blaise

Reputation: 13479

You can, but you would have to write a filter that changes the structure of your data to the following:

$scope.data = [
    {A: {'101': true, '102': true, '103': true}}, 
    {B: {'101': false, ...}},
    {C: ...}
]

And then you can write your table like this:

   <table>
     <tr>
       <th>name</th>
       <th ng-repeat="(column, value) in data[0]">{{column}}</th>
     </tr>
     <tr ng-repeat="row in data">
       <td ng-repeat="(column, value) in data[0]">{{row[column] ? 'Yes' : 'No'}}</td>
     </tr>
   </table>

Example filter:

yourModule.filter('makeNgRepeatable', function(){
    return function(oldStructure) {
       // Add code here to convert oldStructure to newStructure.
       return newStructure;
    }
});

In your controller, inject makeNgRepeatableFilter and do

$scope.data = makeNgRepeatableFilter([{ name:A, id:101 }, ...]);

Upvotes: 1

Jonathan
Jonathan

Reputation: 3644

You can pack this into a table and then resolve with multiple ng-repeats which cell is YES or NO.

Take a look at this plnkr, it demonstrates how this could be achieved.

http://plnkr.co/edit/QI8ZrsbwYuJUeV4DNWGl?p=preview

First you collect all distinct ids and names.

$scope.names = $scope.listvalues.map(function(d){return d.name}).unique();
$scope.ids = $scope.listvalues.map(function(d){return d.id}).unique();

Note: In the plnkr I defined the functions unique and contains. If you use some other libraries like underscore those functions may already be present.

Then you define a function to determine if a specific cell should be true or false.

  $scope.hasValue = function(name, id)  {
    for(var i = 0; i < $scope.listvalues.length; ++i)
      if($scope.listvalues[i].name === name && $scope.listvalues[i].id === id)
        return true;
    return false;
  }

However, it would be simpler if you can convert your listvalues into a reasonable structure. This would prevent some of the overhead.

Upvotes: 0

Related Questions