Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display dynamic knockout observable array in table

Given an observable array 'sampleList' defined inside the viewModel.

 [
   { 
     name: abc, 
     age:  40,
     InterestLevel: {
        trekking: 50,
        hiking : 43
     }  
   },

  { 
     name: def, 
     age:  34,
     InterestLevel: {
       cricket: 55,
       cycling: 75
     }  
   }
 ]

How to generate the following table from the above data using KO custom binding or any best possible way.

-------------------------------------

name  age  Interest  InterestLevel
-------------------------------------

abc   40    trekking    50
abc   40    hiking      43
def   34    cricket     55
def   34    cycling     75

[please note that the keys inside InterestLevel are dynamic].

like image 809
Felix Avatar asked Jul 16 '26 10:07

Felix


2 Answers

First, you'll have to de-normalize your data:

this.TableData = ko.computed(function()
    {
    var data = ko.unwrap(this.sampleList)
    var res = ko.observableArray();

    for (var i in data)
    {
        for (var il in data[i].InterestLevel)
        {
            var ild = data[i].InterestLevel[il];
            res.push({ name: data[i].name, age: data[i].age, Interest: il, InterestLevel: ild });
        }
    }

    return res;
}, this);

Then bind your table to TableData():

<table>
    <thead>
        <tr>
             <td>Name</td>
             <td>Age</td>
             <td>Interest</td>
             <td>Interest Level</td>
        </tr>
    </thead>

    <tbody data-bind="foreach: TableData()">
        <tr>
             <td data-bind="text: name">Name</td>
             <td data-bind="text: age">Age</td>
             <td data-bind="text: Interest">Interest</td>
             <td data-bind="text: InterestLevel">Interest Level</td>                
        </tr>
    </tbody>
</table>

See Fiddle

like image 101
haim770 Avatar answered Jul 18 '26 02:07

haim770


Okay, so I got the wrong end of the stick. Here is the plnker

var jsonObj = [
   { 
     name: "abc", 
     age:  40,
     InterestLevel: {
        trekking: 50,
        hiking : 43
     }  
   },

  { 
     name: "def", 
     age:  34,
     InterestLevel: {
       cricket: 55,
       cycling: 75
     }  
   }
 ];

var newArr = [];
for (var i = 0; i < jsonObj.length; i++){
    var item = jsonObj[i];

    var newItem = {};
    var itemsToBeCreated = []; // holds new items that need to be created

    for (var key in item) {
        if (typeof item[key] !== "object") {
            newItem[key] = item[key]; // copy the new item
        } else {
          for (var deeperKey in item[key]) {
            var obj = {};
            obj[deeperKey] = item[key][deeperKey];
            itemsToBeCreated.push(obj);
          }
        }
    }

    for (var y = 0; y < itemsToBeCreated.length; y++) {
      newArr.push(_.extend(itemsToBeCreated[y], newItem))
    }
}

So this is a bit difficult to explain. Basically:

  1. iterate through all items in jsonObj
  2. create a new item with all the primitive values from the item
  3. if we hit an object go into it
  4. loop through all the primitive values in the object
  5. create a bare object of that object
  6. add to an array for later use
  7. when we have finished looping, loop through the array we created earlier
  8. Each object in there extend with the item created at the beginning of the loop
  9. push these into a completely new array

The idea is that with each child object we grab out a single key and value and turn it into its own object. Then with the cloned parent object (minus the child object) we extend the single objects with the cloned parent thus making a completely new row.

I don't know if I can explain it any better.

My solution will work with any object you have that has a single level of child objects. So if your model changes this should still hold strong.

like image 33
Callum Linington Avatar answered Jul 18 '26 00:07

Callum Linington



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!