1

I need to set the row span value dynamically based on a condition.

The Array I have:

 $scope.approvalitems = [
                 { ReqId: '100' Date: '02-02-2015', AssociateID: '346248', },
                 { ReqId: '101' Date: '02-02-2015', AssociateID: '346248', },
                                ------------------------------------------  
                 { ReqId: '102' Date: '06-02-2015', AssociateID: '123456', },
                 { ReqId: '103' Date: '06-02-2015', AssociateID: '123456', },
                 { ReqId: '104' Date: '06-02-2015', AssociateID: '123456', },
                                -------------------------------------------
                 { ReqId: '105', Date: '07-02-2015', AssociateID: '309645',},
                 { ReqId: '106', Date: '07-02-2015', AssociateID: '309645',},
                                --------------------------------------------
                 { ReqId: '107', Date: '08-02-2015', AssociateID: '346248',}
        ];

Need to set the row span value =(count of items ) having both the DATE and AssociateID values same.

I'm unable to structute the table using ng-repeat , tried using group but unable to get the count of unique elements of Date and AssociateID using groupBy in filter . Looking for an approach to solve this.

Need to get like this.

Date       AssociateID      Time
-----------|----------|-----------------------
02-02-2015 |346248    | Click here for the time
-----------|----------|
02-02-2015 |346248    |
-----------|----------|----------------------
06-02-2015 |123456    | Click here for the time
-----------|----------|
06-02-2015 |123456    |
-----------|----------|
06-02-2015 |123456    |
-----------|----------|----------------------
07-02-2015 |309645    | Click here for the time
-----------|----------|
07-02-2015 |309645    |
-----------|----------|----------------------   
08-02-2015 |346248    | Click here for the time

Here is my Fiddle

So how to acheive this , should i need to sort it before binding the array , if so pls guide me or is there any better way to acheive this.I'm a newbie to angular js.

2 Answers 2

1

In your case i would sort the by using an object as map.

$scope.createObjectMap = function () {
        var items = {};
        angular.forEach($scope.approvalitems, function (value, key) {
            if (!items['id' + value.AssociateID]) { // +id because properties shound not begin with numbers
                items['id' + value.AssociateID] = new Array();
            }
            items['id' + value.AssociateID].push(value);
        });
        return items;
    }

And then i would use two ng-repeat, first to iterate over the object and th second to iterate over the values (an array). Take a look to my fiddle.

If someone have a better solution please let me know.

Sign up to request clarification or add additional context in comments.

4 Comments

why you think properties shound not begin with numbers?
@Grundy I prefer property names witch are valid variable names. Because if often pass data via json to a rest-api and property names witch are not starting with a number make my life easier.
@Christoph Thanks for the answer , but i need to set the value of rowspan by comparing both AssociateID and Date , or can i get the count of similar items ,push it to an array and use it in ng-repeat.will that work ?Thanx for the help
I'm not sure that i understand your question. You can access the length of "group" in my example (fiddle). jsfiddle.net/90n55ctb
1

You can create a filter that will be apply to the ngRepeat directive. But you must be careful with this digest cycle error :

10 $digest() iterations reached. Aborting!

You can get these error because we are returning different objects on each $digest cycle, or we are altering the data too many times.

So a good option is to Memoizing Angular filters to stop digest errors. You can use the _.memoize method from the lodash library to make them run faster and avoid nasty digest loops. Don't forget to include the lodash script tag in your html.

So :

Controller

(function(){

function Controller($scope) {

  $scope.approvalitems = [
          { ReqId: '101', Date: '02-02-2015', AssociateID: '346248', },
           { ReqId: '102', Date: '02-02-2015', AssociateID: '346248', },
           { ReqId: '103', Date: '06-02-2015', AssociateID: '123456', },
           { ReqId: '104', Date: '06-02-2015', AssociateID: '123456', },
           { ReqId: '105', Date: '06-02-2015', AssociateID: '123456', },
           { ReqId: '106', Date: '07-02-2015', AssociateID: '309645', },
           { ReqId: '107', Date: '07-02-2015', AssociateID: '309645', },
           { ReqId: '108', Date: '08-02-2015', AssociateID: '346248', }
  ];

}

angular
.module('app', [])
.controller('ctrl', Controller);

})();

Filter

(function(){

  function filter(){

    function group(input, search) {

        if (!input) { return; }
        //Create our filtered object
         var filtered = {};
         //Split our search params
         var field = search.split(',');
         //For all input
         input.forEach(function(item) {
           //Retrieve field param by mapping over the item element
           var key = field.map(function(elm){
             return item[elm.replace(/ /g,'')];
           });
           //If our object get the key, retrieve it, otherwise, create an empty array
           filtered[JSON.stringify(key)] = filtered[JSON.stringify(key)] || [];
           //Push item data into our object
           filtered[JSON.stringify(key)].push(item);
         });

       return filtered;
   }

   //Memoize the filter function by using lodash memoize
   return _.memoize(group);

  }

  angular
    .module('app')
    .filter('group', filter);

})();

HTML

  <body ng-app="app" ng-controller="ctrl">

    <table style="width: 30%" border="3">
       <tr>
           <th>Date</th>
           <th>AssociateID</th>
           <th>SwipeSummary</th>
       </tr>
       <tr ng-repeat="(key, value) in approvalitems | group: 'Date,AssociateID'" >
         <td>
            <div ng-repeat="item in value">
              {{item.Date}}
            </div>
         </td>
         <td>
            <div ng-repeat="item in value">
              {{item.AssociateID}}
            </div>
         </td>
         <td>
           <span>Click here for time</span>
         </td>
       </tr>

    </table>

 </body>

You can see the Working Plunker

2 Comments

Thanks for the answer +1 . so you say its better to create a custom filter with memozie to avoid exception as the table structure gets iterated many times, also i've changed the correct table structure in the question,help on that is welcome.
I dont want the td values in date and associate id grouped inside a single cell , need to be just like a row .only the 'Time' cell to be grouped based on the associateid and date. You can look at the table structure in the question.Thank you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.