redrom
redrom

Reputation: 11642

How to use modulo operator for table row and col structure?

I have following table with td written using ng-repeat:

<div class="row">
            <div class="col-sm-10">
              <table class="customAttributesTable">
                <tbody>
                <tr>
                  <td class="col-sm-2" ng-repeat="customField in basicInfoCustomFields">
                    <label for="customer">{{ 'CUSTOMER' | translate }} </label>
                    <input type="text" ng-model="order.customer.name"  class="form-control" id="customer" />
                  </td>
                </tr>
                </tbody>
              </table>
            </div>
          </div>

I would like to ask how can i do following:

Max count of columns in row can be 5, if items count is higher than 5 table should to contain new row.

If count of items in row is lower than 5 are missing values to count 5 replaced by tag:

  <td class="col-sm-2">

  </td>

Because the data for the table are stored as the Array of the objects i have to use modulo operator to do this.

Have somebody the idea, how can i do it please?

Many Thanks for any advice.

EDIT:

Based on the anpsmn reply i tried following:

<!-- CUSTOM FIELDS -->
          <div class="row">
            <div class="col-sm-10">
              <table class="customAttributesTable">
                <tbody>
                <tr ng-switch on="$index%5==0" ng-repeat="customField in basicInfoCustomFields">
                  <td ng-repeat="i in [0,1,2,3,4]" class="col-sm-2" >
                    <label for="customer">{{basicInfoCustomFields[$parent.$index+i].label}} </label>
                    <input type="text" ng-model="basicInfoCustomFields[$parent.$index+i].value"  class="form-control" id="customer" />
                  </td>
                </tr>
                </tbody>
              </table>
            </div>
          </div>
          <!-- !!CUSTOM FIELDS -->

But it producing result like this (scope array has only 3 items):

enter image description here

Upvotes: 2

Views: 9817

Answers (2)

anpsmn
anpsmn

Reputation: 7257

Better solution is to have a if-condition for the repeat

ng-if="$index%5"

Update:

Added - for filling rest of the columns if its less than 5

<span>{{basicInfoCustomFields[$parent.$index+i].name || "-"}}</span>

Plunkr

Demo

  var app = angular.module('app', []);

    app.controller('MainCtrl', function($scope) {

      $scope.basicInfoCustomFields = [
          {"name":"Anto"},
          {"name":"Julie"},
          {"name":"John"},
          {"name":"Doe"},
          {"name":"Ray"},
          {"name":"Sassy"},
          {"name":"Wright"},
          {"name":"Fred"},
          {"name":"Flintstone"},
          {"name":"Price"},
          {"name":"Dave"},
          {"name":"Neo"},
          {"name":"Jack"},
          {"name":"Lee"},
          {"name":"Eoin"},
          {"name":"Victor"},
          {"name":"Rita"}
      ];

    });
 /* Put your css in here */

    .row-orange { background: orange; margin-bottom: 10px;}
    .row-orange td {border-bottom: 1px solid #fff;}
    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.min.js"></script>
    <body ng-app="app"  ng-controller="MainCtrl">
       
        <div class="container">
           <div class="row">
                <div class="col-xs-12">
                  <table class="customAttributesTable">
                    <tbody >
                     <tr ng-if="$index%5==0"  ng-repeat="customField in basicInfoCustomFields" class="row-orange" >
                       <td ng-repeat="i in [0,1,2,3,4]"    class="col-xs-2">
                          <span>{{basicInfoCustomFields[$parent.$index+i].name || "-"}}</span>  
                       </td>
                     </tr>
                    </tbody>
                  </table>
                </div>
              </div>
        </div>
       
      </body>

Upvotes: 5

Sergiu Paraschiv
Sergiu Paraschiv

Reputation: 10153

You could ng-repeat="customFieldId in [0, 1, 2, 3, 4]" and then {{ basicInfoCustomFields[customFieldId] }}. That way you know there will always be five tds. You can also ng-if="customFieldId < basicInfoCustomFields.length" to know if the column data exists.

For more than 5 items you could add a second ng-repeat="customFieldId in [5, 6, 7, 8, 9]" inside a <tr ng-if="basicInfoCustomFields.length > 5">.

You could then write a directive to use inside the trs so that you don't duplicate the code inside them.

I'm thinking about something like this:

<table ng-controller="myCtrl">
<tbody>
    <tr>
        <td class="col-sm-2" ng-repeat="id in range(0, 5)">
            <span ng-if="four.length > id">{{four[id].text}}</span>
        </td>
    </tr>

    <tr>
        <td class="col-sm-2" ng-repeat="id in range(0, 5)">
            <span ng-if="five.length > id">{{five[id].text}}</span>
        </td>
    </tr>

    <tr>
        <td class="col-sm-2" ng-repeat="id in range(0, 5)">
            <span ng-if="six.length > id">{{six[id].text}}</span>
        </td>
    </tr>

    <tr>
        <td class="col-sm-2" ng-repeat="id in range(5, 10)">
            <span ng-if="six.length > id">{{six[id].text}}</span>
        </td>
    </tr>
</tbody>

where

function myCtrl($scope) {
    $scope.range = function(from, to) {
        var i, a = [];
        for(i = from; i < to; i++) {
            a.push(i);
        }
        return a;
    };

    $scope.four = [
        {text:'1'},
        {text:'2'},
        {text:'3'},
        {text:'4'}
    ];

    $scope.five = [
        {text:'1'},
        {text:'2'},
        {text:'3'},
        {text:'4'},
        {text:'5'}
    ];

    $scope.six = [
        {text:'1'},
        {text:'2'},
        {text:'3'},
        {text:'4'},
        {text:'5'},
        {text:'6'}
    ];
}

You could further improve this by doing this:

<tr ng-repeat="row in [0, 1]">
    <td class="col-sm-2" ng-repeat="id in range(row * 5, (row + 1) * 5)">
        <span ng-if="six.length > id">{{six[id].text}}</span>
    </td>
</tr>

This way you can handle multiple number of potential rows with no code duplication.

Upvotes: 1

Related Questions