2

Here's a fiddle with the desired table and the Javascript function containing the array from where I want to populate the table, what I don't figure out is how, because if I use rowspan and colspan I have to create different <tr> for each product...

If there's another way to get the desired table I'd love to know about it... The main question here is: How could I use ng-repeat in a table that uses rowspan and colspan?

Also, the colspan and rowspan values at the <thead> can't be static as in the jsfiddle since each row may contain different amount of products... So the second question is: How could I dynamically set the rowspan value? they should be specified in each table row..

4 Answers 4

7

This is possible if you let the rowspan depend on inventory.length for the current transaction, and then you use nested ng-repeats.

Here we go:

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

function MainCtrl($scope) {
    var vm = $scope;
    vm.hello = 123;
    vm.transactions = [{
        id: 1,
        cost: 100,
        transaction_type: { id: 1, name: 'Sell' },
        client: { id: 2, name: 'XCLIENT' },
        inventory: [
            { id: 1, quantity: 4, product: { id: 1, name: 'Cup' }, product_condition: { id: 2, name: 'New' } },
            { id: 2, quantity: 10, product: { id: 2, name: 'Shirt' }, product_condition: { id: 2, name: 'New' } }
        ]
    }, {
        id: 2,
        cost: 40,
        transaction_type: { id: 2, name: 'Buy' },
        supplier: { id: 3, name: 'XSUPPLIER' },
        inventory: [
            { id: 1, quantity: 2, product: { id: 1, name: 'Cup' }, product_condition: { id: 2, name: 'New' } },
            { id: 2, quantity: 5, product: { id: 6, name: 'Pants' }, product_condition: { id: 2, name: 'New' } }
        ]
    }];
}
table,
th,
td {
  border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
  <table ng-controller="MainCtrl">
    <thead>
      <div>
        <tr>
          <td rowspan=2>Movement</td>
          <td colspan=3>Products</td>
          <td rowspan=2>Supplier</td>
          <td rowspan=2>Cost</td>
        </tr>
        <tr>
          <td>Name</td>
          <td>Quantity</td>
          <td>Condition</td>
        </tr>
      </div>
    </thead>
    <tbody ng-repeat="t in transactions">
      <tr>
        <td rowspan="{{t.inventory.length}}">Sell</td>
        <td>{{t.inventory[0].product.name}}</td>
        <td>{{t.inventory[0].quantity}}</td>
        <td>{{t.inventory[0].product_condition.name}}</td>
        <td rowspan="{{t.inventory.length}}">XCLIENT</td>
        <td rowspan="{{t.inventory.length}}">$100</td>
      </tr>
      <tr ng-repeat="item in t.inventory" ng-if="$index > 0">
        <td>{{item.product.name}}</td>
        <td>{{item.quantity}}</td>
        <td>{{item.product_condition.name}}</td>
      </tr>
    </tbody>
  </table>
</div>

(Fiddle)

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

4 Comments

There's a thing with your answer, the first product listed is static, the one that is Cup, 4, New...
Thanks!!, If you know about a way to have it all in a single <tr> it would be awesome! I mean the whole transaction data including the products...
That's not possible, as far as I know.
I believe instead of ng-if you can do ng-repeat="item in t.inventory.slice(1)
3

Here it is the totally dynamic way including dynamic rowspan :

HTML:

<div ng-app>
  <h3>Here's what I want it to be</h3>
  <div ng-controller="MainCtrl">  

  <table >
    <thead>
      <tr>
        <td rowspan='{{rowspan}}'>Movement</td>
        <td colspan='{{rowspan}}'>Products</td>
        <td rowspan='{{rowspan}}'>Supplier</td>
        <td rowspan='{{rowspan}}'>Cost</td>
      </tr>
      <tr>
        <td>Name</td>
        <td>Quantity</td>
        <td>Condition</td>
      </tr>
    </thead>
    <tbody ng-repeat='t in transactions'>     
      <tr ng-init='invCustom=(t.invetory.splice(1))'>
        <td rowspan='{{rowspan}}'>{{t.transaction_type.name}}</td>

        <td>{{t.invetory[0].product.name}}</td>
        <td>{{t.invetory[0].quantity}}</td>
        <td>{{t.invetory[0].product_condition.name}}</td>

        <td ng-if='$index==0' rowspan='{{rowspan}}'>{{t.client.name}}</td>
        <td ng-if='$index==1' rowspan='{{rowspan}}'>{{t.supplier.name}}</td>
        <td rowspan='{{rowspan}}'>{{ t.cost | currency }}</td>
      </tr>
      <tr ng-repeat='tsub in invCustom'> 
        <td>{{tsub.product.name}}</td>
        <td>{{tsub.quantity}}</td>
        <td>{{tsub.product_condition.name}}</td>
      </tr>
    </tbody>  
  </table>
  </div>
    <h4>This data isn't loaded from the controller, I'd like to know how to use ng-repead in this case</h4>

</div>

JS:

function MainCtrl($scope) {
 //var vm = this;
  $scope.rowspan = 3;
  $scope.transactions = [{
    id: 1,
    cost: 100,
    transaction_type: {
      id: 1,
      name: 'Sell'
    },
    client: {
      id: 2,
      name: 'XCLIENT'
    },
    invetory: [{
      id: 1,
      quantity: 4,
      product: {
        id: 1,
        name: 'Cup'
      },
      product_condition: {
        id: 2,
        name: 'New'
      }
    }, {
      id: 2,
      quantity: 10,
      product: {
        id: 2,
        name: 'Shirt'
      },
      product_condition: {
        id: 2,
        name: 'New'
      }
    },
     {
      id: 3,
      quantity: 101,
      product: {
        id: 3,
        name: 'Shirt_C'
      },
      product_condition: {
        id: 3,
        name: 'New_C'
      }
    }]
  }, {
    id: 2,
    cost: 40,
    transaction_type: {
      id: 2,
      name: 'Buy'
    },
    supplier: {
      id: 3,
      name: 'XSUPPLIER'
    },
    invetory: [{
      id: 1,
      quantity: 2,
      product: {
        id: 1,
        name: 'Cup'
      },
      product_condition: {
        id: 2,
        name: 'New'
      }
    }, {
      id: 2,
      quantity: 5,
      product: {
        id: 6,
        name: 'Pants'
      },
      product_condition: {
        id: 2,
        name: 'New'
      }
    },
              {
      id: 3,
      quantity: 55,
      product: {
        id: 7,
        name: 'Pants_C'
      },
      product_condition: {
        id: 8,
        name: 'New_C'
      }
    }]
  }];
}

Comments

1

try below code and do not forgot to include angular JS library....

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.2/angular.min.js
"></script>
<div ng-app>
  <h3>Here's what I want it to be</h3>
  <div ng-controller="MainCtrl">  
  <table >
    <thead>
      <tr>
        <td rowspan=2>Movement</td>
        <td colspan=3>Products</td>
        <td rowspan=2>Supplier</td>
        <td rowspan=2>Cost</td>
      </tr>
      <tr>
        <td>Name</td>
        <td>Quantity</td>
        <td>Condition</td>
      </tr>
    </thead>
    <tbody ng-repeat='t in transactions' ng-init='i=0'>     
      <tr>
        <td rowspan=2>{{t.transaction_type.name}}</td>

        <td>{{t.invetory[i].product.name}}</td>
        <td>{{t.invetory[i].quantity}}</td>
        <td>{{t.invetory[i].product_condition.name}}</td>

        <td ng-if='$index==0' rowspan=2>{{t.client.name}}</td>
        <td ng-if='$index==1' rowspan=2>{{t.supplier.name}}</td>
        <td rowspan=2>{{ t.cost | currency }}</td>
      </tr>
      <tr>        
         <td>{{t.invetory[i+1].product.name}}</td>
        <td>{{t.invetory[i+1].quantity}}</td>
        <td>{{t.invetory[i+1].product_condition.name}}</td> 
      </tr>
    </tbody>

  </table>
  </div>
    <h4>This data isn't loaded from the controller, I'd like to know how to use ng-repead in this case</h4>

</div>

1 Comment

This limits the rowspan to just two products, what I need is a dynamic rowspan per table row, do you mind making a jsfiddle?
0

How could I use ng-repeat in a table that uses rowspan and colspan?

Yes you can use, I will put a very basic example and not fix the entire thing for you.

<table>
    <tr ng-repeat="item in mylist">
        <td ng-if="someCondition2" rowspan="2">AAA</td>
        <td ng-if="someCondition1" colspan="2">BBB</td>
        <td ng-if="someCondition3">CCC</td>
    <tr>
</table>

This way you can conditionally add rowspan or colspan where ever required, hope you get the idea.

2 Comments

There wouldn't be a problem for me if there would be a single <tr>, if you could help making the table look like the jsfiddle and having the ng-repeat just in one <tr> then your answer would be helpful
What I thought was to put the ng-repeat in the <tbody> tag, but that's bad practice, but basically my problem is also related to the colspan and rowspan values at the <thead> they can't be static, they must be calculated for each table row...

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.