Eshiett Oto-obong
Eshiett Oto-obong

Reputation: 418

How to perform foreach loop in knockout.js for a multiple row and column list

enter image description here

I have read about each function in knockout js, but i am trying to perform one where there are 3 rows, so after a row of 3 users are populated, knock out should go to the next row and populate it, how do i achieve this??

Upvotes: 3

Views: 2099

Answers (1)

adiga
adiga

Reputation: 35222

You need to group the users based on their indexes. The end goal is to create an array of arrays where the inner arrays contain the data for each column. You can create a computed property like this:

var viewModel = function() {
  var self = this;

  self.users = [
   { name: "name 1"}, 
   { name: "name 2"}, 
   { name: "name 3"}, 
   { name: "name 4"}, 
   { name: "name 5"}, 
   { name: "name 6"}, 
   { name: "name 7"}, 
 ];

  // this array looks: [[user1,user2,user3], [user4,user5,user6]]
  self.groupedUsers = ko.computed(function() {
    var rows = [];

    self.users.forEach(function(user, i) {
      // whenever i = 0, 3, 6 etc, we need to initialize the inner array
      if (i % 3 == 0)
        rows[i/3] = [];

      rows[Math.floor(i/3)][i % 3] = user;
    });

    return rows;
  });
};

ko.applyBindings(new viewModel());

And in your html:

<table>
  <tbody data-bind="foreach: groupedUsers">
    <tr data-bind="foreach: $data">
      <td data-bind="text: name">
      </td>
    </tr>
  </tbody>
</table>

$data here is the inner array in context. You can read about binding context here.

Here's a fiddle for testing


CSS options:

I'm not an expert, but the key here is whether you have a container for each row. If you didn't have a separator between each row, you could achieve this using pure css. You could use float: left on the user containers and it would take the number of users per line based on the screen size and container width.

The same line of argument can be made if you're using a framework like bootstrap or foundation which have grid classes to help out. You would contain all the columns within a row class and the grid would automatically adjust based on the screen size and custom col-md and col-sm classes you set based on your device-level requirement.

Upvotes: 3

Related Questions