I am having problems displaying data in the accordian, as shown in photo.
No matter what row you click, the same "hidden row" is displayed. And I see why... the following line sets the target of the accordian element.
<tr data-toggle="collapse" data-target="#demo1" class="accordion-toggle">
Somehow I need to make "#demo1" unique, and the hidden row as well.
Here is the code: How would I make sure each row gets it's own unique target id, as well as the hidden row?
Thanks!
<table class="table table-striped table-bordered notranslate">
<thead>
<tr>
<th style="width: 10%">ID</th>
<th>First</th>
<th>Last</th>
<th>Email</th>
<th>Phone</th>
<th>Actions</th>
</tr>
</thead>
<tbody data-bind="foreach: customers">
<tr data-toggle="collapse" data-target="#demo1" class="accordion-toggle">
<td>
<i class="fa fa-plus" style="cursor: pointer"></i>
</td>
<td data-bind="text: firstName"></td>
<td data-bind="text: lastName"></td>
<td data-bind="text: email"></td>
<td data-bind="text: phone"></td>
<td> <i class="fa fa-pencil mr-1" data-bind="click: $root.editCustomer"></i> <i class="fa fa-trash mr-1" data-bind="click: $root.deleteCustomer"></i></td>
</tr>
<tr>
<td colspan="6" class="hiddenRow">
<div class="accordian-body collapse" id="demo1" >
<table class="" style="background-color: lightyellow; width: 100%;">
<tbody>
<tr>
<th>Address 1</th>
<th>Address 2</th>
<th>City</th>
<th>State</th>
<th>Zip Code</th>
</tr>
<tr>
<td data-bind="text: address1"></td>
<td data-bind="text: address2"></td>
<td data-bind="text: city"></td>
<td data-bind="text: state"></td>
<td data-bind="text: zip"></td>
</tr>
</table>
</div>
</td>
</tr>
</tbody>
</table>
You should make sure the data-target and matching hidden row id are unique for each row. You can use the attr data-binding to dynamically set these attributes and utilize the $index context observable property of the foreach binding to construct unique matching values.
This could result in for example data-bind="attr: { 'data-target': '#demo' + $index() }" for the data-target and data-bind="attr: { id: 'demo' + $index() }" for the matching hidden row id. Have a look at the shortened example below:
ko.applyBindings({
customers: [{}, {}, {}, {}]
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<table class="table table-striped table-bordered notranslate">
<thead>
<tr>
<th style="width: 10%">ID</th>
<th>First</th>
<th>Last</th>
<th>Email</th>
<th>Phone</th>
<th>Actions</th>
</tr>
</thead>
<tbody data-bind="foreach: customers">
<tr data-toggle="collapse" data-bind="attr: { 'data-target': '#demo' + $index() }" class="accordion-toggle">
<td colspan="6">Click to toggle</td>
</tr>
<tr>
<td colspan="6" class="hiddenRow">
<div class="accordian-body collapse" data-bind="attr: { id: 'demo' + $index() }">
<table class="" style="background-color: lightyellow; width: 100%;">
<tbody>
<tr>
<th>Address 1</th>
<th>Address 2</th>
<th>City</th>
<th>State</th>
<th>Zip Code</th>
</tr>
<tr>
<td colspan="5">...</td>
</tr>
</table>
</div>
</td>
</tr>
</tbody>
</table>
Related
I have a table and I want to compare it to the table.
If A2 > A1, I want to set the row to red color.
I can access data with Each command, but I have difficulty in the class to assign.
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<table class="table table-sm table-bordered mt-4" style="font-size: 12px; ">
<thead>
<th>
<center>Stok</center>
</th>
<th>
<center>A1</center>
</th>
<th>
<center>A2</center>
</th>
</thead>
<tbody id="arsivTablosu">
<tr id="satir">
<td>A1</td>
<td id="envanter" class="">
<center>44</center>
</td>
<td id="kritikStok" class="">
<center>45</center>
</td>
</tr>
<tr id="satir">
<td>A2</td>
<td id="envanter" class="">
<center>50</center>
</td>
<td id="kritikStok" class="">
<center>10</center>
</td>
</tr>
<tr id="satir">
<td>A3</td>
<td id="envanter" class="">
<center>26</center>
</td>
<td id="kritikStok" class="">
<center>27</center>
</td>
</tr>
<tr id="satir">
<td>A4</td>
<td id="envanter" class="">
<center>40</center>
</td>
<td id="kritikStok" class="">
<center>39</center>
</td>
</tr>
</tbody>
</table>
You can use .each loop to iterate through your tbody trs then use .find("td:eq(1) center") to get value of td from 2nd column and .find("td:eq(2) center") to get value from 3rd column then compare both and add class depending on this .
Demo Code :
//loop through tr
$("#arsivTablosu tr").each(function() {
//check the value of 2 & 3 td
parseInt($(this).find("td:eq(2) center").text()) > parseInt($(this).find("td:eq(1) center").text()) ? $(this).addClass("red_color") : ""
})
.red_color {
background-color: red
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<table class="table table-sm table-bordered mt-4" style="font-size: 12px; ">
<thead>
<th>
<center>Stok</center>
</th>
<th>
<center>A1</center>
</th>
<th>
<center>A2</center>
</th>
</thead>
<tbody id="arsivTablosu">
<tr>
<td>A1</td>
<td>
<center>44</center>
</td>
<td>
<center>45</center>
</td>
</tr>
<tr>
<td>A2</td>
<td>
<center>50</center>
</td>
<td>
<center>10</center>
</td>
</tr>
<tr>
<td>A3</td>
<td>
<center>26</center>
</td>
<td>
<center>27</center>
</td>
</tr>
<tr>
<td>A4</td>
<td>
<center>40</center>
</td>
<td>
<center>39</center>
</td>
</tr>
</tbody>
</table>
I added tooltip in my table's 2nd column but it is pushiing my last column away.
$(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip();
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
<div class="container">
<table class="table">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>Default</td>
<td data-toggle="tooltip" data-placement="top" title="Hooray!">Defaultson</td>
<td>def#somemail.com</td>
</tr>
<tr class="success">
<td>Success</td>
<td data-toggle="tooltip" data-placement="top" title="Hooray!">Doe</td>
<td>john#example.com</td>
</tr>
</tbody>
</table>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
You can just add data-container="body" in your HTML in this way:
$(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip();
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
<div class="container">
<table class="table">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>Default</td>
<td data-toggle="tooltip" data-container="body" data-placement="top" title="Hooray!">Defaultson</td>
<td>def#somemail.com</td>
</tr>
<tr class="success">
<td>Success</td>
<td data-toggle="tooltip" data-container="body" data-placement="top" title="Hooray!">Doe</td>
<td>john#example.com</td>
</tr>
</tbody>
</table>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
or can add {container: 'body'} to your JavaScript in this way:
$(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip({container: 'body'});
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
<div class="container">
<table class="table">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>Default</td>
<td data-toggle="tooltip" data-placement="top" title="Hooray!">Defaultson</td>
<td>def#somemail.com</td>
</tr>
<tr class="success">
<td>Success</td>
<td data-toggle="tooltip" data-placement="top" title="Hooray!">Doe</td>
<td>john#example.com</td>
</tr>
</tbody>
</table>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
EDIT:
If you want your tooltip to be on text instead of td you can create an inner element like span and add tooltip on that item. Try this way:
$(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip();
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
<div class="container">
<table class="table">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>Default</td>
<td>
<span data-toggle="tooltip" data-container="body" data-placement="top" title="Hooray!">Defaultson</span>
</td>
<td>def#somemail.com</td>
</tr>
<tr class="success">
<td>Success</td>
<td>
<span data-toggle="tooltip" data-container="body" data-placement="top" title="Hooray!">Doe</span></td>
<td>john#example.com</td>
</tr>
</tbody>
</table>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<table class="table">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>Default</td>
<td data-toggle="tooltip" data-placement="top" title="Hooray!" data-container="body">Defaultson</td>
<td>def#somemail.com</td>
</tr>
<tr class="success">
<td>Success</td>
<td data-toggle="tooltip" data-placement="top" title="Hooray!" data-container="body">Doe</td>
<td>john#example.com</td>
</tr>
</tbody>
</table>
</div>
<script>
$(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip();
});
</script>
</body>
</html>
just add data-container="body"
<td data-toggle="tooltip" data-placement="top" title="Hooray!" data-container="body">Defaultson</td>
try this way :
$(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip();
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
<div class="container">
<table class="table">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>Default</td>
<td><p data-toggle="tooltip" data-placement="top" title="Hooray!">Defaultson</p></td>
<td>def#somemail.com</td>
</tr>
<tr class="success">
<td>Success</td>
<td><p data-toggle="tooltip" data-placement="top" title="Hooray!">Doe</p></td>
<td>john#example.com</td>
</tr>
</tbody>
</table>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
edit <tbody> like
<tbody>
<tr data-toggle="tooltip">
<td>Default</td>
<td data-placement="top" title="Hooray!">Defaultson</td>
<td>def#somemail.com</td>
</tr>
<tr class="success" data-toggle="tooltip">
<td>Success</td>
<td data-placement="top" title="Hooray!">Doe</td>
<td>john#example.com</td>
</tr>
</tbody>
this. put data-toggle="tooltip" into <tr> tag
I am trying to duplicate a specific line in my table when I click in "duppliquer" button
See my code to create my table below
<table id="myTable" class="table table-striped table-bordered table order-list" data-page-length='100'>
<thead>
<tr>
<th style="width: 5%">Col 1</th>
<th style="width: 5%">Col 2</th>
<th style="width: 5%">Col 3</th>
<th style="width: 5%">Col 4</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">Test1</td>
<td align="center">Test2</td>
<td align="center">Test3</td>
<td align="center">
<a class="Duppliquer" title="Duppliquer" data-toggle="tooltip" style="cursor: pointer;"><i class="material-icons">control_point_duplicate</i></a>
</td>
</tr>
<tr>
<td align="center">Test4</td>
<td align="center">Test5</td>
<td align="center">Test6</td>
<td align="center">
<a class="Duppliquer" title="Duppliquer" data-toggle="tooltip" style="cursor: pointer;"><i class="material-icons">control_point_duplicate</i></a>
</td>
</tr>
</tbody>
I know that I have to use Javascript ou Jquery, but I don't understand how to get the line that i want to duplicate
I made a lot of research on this subject, but cannot find any answer ...
You should get the current row element and then use clone(true) function to clone it and finally append the cloned row into the table so that it is placed after the current row elemnt. Here is an example:
$(".Duppliquer").click(function(){
var $rw = $(this).closest( "tr" );
var $new_rw = $rw.clone( true );
$rw.after($new_rw);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="myTable" class="table table-striped table-bordered table order-list" data-page-length='100'>
<thead>
<tr>
<th style="width: 5%">Col 1</th>
<th style="width: 5%">Col 2</th>
<th style="width: 5%">Col 3</th>
<th style="width: 5%">Col 4</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">Test1</td>
<td align="center">Test2</td>
<td align="center">Test3</td>
<td align="center">
<a class="Duppliquer" title="Duppliquer" data-toggle="tooltip" style="cursor: pointer;"><i class="material-icons">control_point_duplicate</i></a>
</td>
</tr>
<tr>
<td align="center">Test4</td>
<td align="center">Test5</td>
<td align="center">Test6</td>
<td align="center">
<a class="Duppliquer" title="Duppliquer" data-toggle="tooltip" style="cursor: pointer;"><i class="material-icons">control_point_duplicate</i></a>
</td>
</tr>
</tbody>
EDIT:
according to the comments the following code will also change the first cell of copied row:
$(".Duppliquer").click(function(){
var $rw = $(this).closest( "tr" );
var $new_rw = $rw.clone( true );
var $first_cell = $new_rw.find("td:first");
$first_cell.html($first_cell.html() + " Copy!");
$rw.after($new_rw);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="myTable" class="table table-striped table-bordered table order-list" data-page-length='100'>
<thead>
<tr>
<th style="width: 5%">Col 1</th>
<th style="width: 5%">Col 2</th>
<th style="width: 5%">Col 3</th>
<th style="width: 5%">Col 4</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">Test1</td>
<td align="center">Test2</td>
<td align="center">Test3</td>
<td align="center">
<a class="Duppliquer" title="Duppliquer" data-toggle="tooltip" style="cursor: pointer;"><i class="material-icons">control_point_duplicate</i></a>
</td>
</tr>
<tr>
<td align="center">Test4</td>
<td align="center">Test5</td>
<td align="center">Test6</td>
<td align="center">
<a class="Duppliquer" title="Duppliquer" data-toggle="tooltip" style="cursor: pointer;"><i class="material-icons">control_point_duplicate</i></a>
</td>
</tr>
</tbody>
//I also recommend using lowercase ids and classes.
$(document).ready(function(){
$(document).on('click', '.Duppliquer', function(e){
e.preventDefault();
var row = $(e.target).closest('tr'),
copy = row.clone();
copy.insertAfter(row);
});
});
Use JQuery find:
$('#myTable').find('tr').click(function () {
var indx = $(this).index() +1; --gets row index
var tr = $(this); --gets row
});
I want to achieve the above image using angular-js ng-repeat. i got a problem for the third column.
<div tasty-table
bind-resource-callback="showTCS.loadAllTCS"
bind-init="showTCS.init"
bind-filters="showTCS.listParams"
bind-reload="showTCS.reloadCallback">
<table class="table table-striped table-condensed table-hover table-bordered table-overflow"
cellpadding="4"
cellspacing="4"
align="center">
<thead tasty-thead bind-not-sort-by="showMainCategory.notSortBy"></thead>
<tbody>
<tr ng-repeat="tcs in rows">
<td>{{tcs.trackName}}</td>
<td>
<table align="left">
<tbody>
<tr ng-repeat="category in tcs.category">
<td>{{category.categoryName}}</td>
<td>
<table> //this one should be on the 3rd <td> of parent table
<tbody>
<tr ng-repeat="skill in category.skill">
<td>{{skill.skillName}}</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
<td align="center">
<a ui-sref="mainCategoryDetails( {mainCatId: mainCategory.mainCat_id} )" class="glyphicon glyphicon-eye-open"></a>
</td>
</tr>
<tr>
<td ng-if="(!rows.length)" colspan="4" class="text-center">No results found.</td>
</tr>
</tbody>
</table>
<div tasty-pagination bind-items-per-page="showTCS.itemsPerPage" bind-list-items-per-page="showTCS.listItemsPerPage"></div>
</div>
This is what i have tried so far and the output is not what i want as shown in the sample image. The problem is how to output the last data which is skills in the third of the parent table.
Found an answer, not quite good since it keeps repeating the tbody but its still ok
<div class="row-fluid" style="padding-top: 2%">
<div tasty-table
bind-resource-callback="showTCS.loadAllTCS"
bind-init="showTCS.init"
bind-filters="showTCS.listParams"
bind-reload="showTCS.reloadCallback">
<table class="table table-striped table-condensed table-hover table-bordered table-overflow"
cellpadding="4"
cellspacing="4"
align="center">
<thead tasty-thead bind-not-sort-by="showTCS.notSortBy"></thead>
<tbody ng-repeat="tcs in rows">
<tr ng-repeat="category in tcs.category">
<td class="text-center" style="vertical-align:middle;">{{tcs.trackName}}</td>
<td class="text-center" style="vertical-align:middle;">{{category.categoryName}}</td>
<td>
<ul class="list-unstyled" >
<li ng-repeat="skill in category.skill">{{skill.skillName}}</li>
</ul>
</td>
<td align="center">
<a ui-sref="mainCategoryDetails( {mainCatId: mainCategory.mainCat_id} )" class="glyphicon glyphicon-eye-open"></a>
<a ui-sref="editMainCategory( {mainCatId: mainCategory.mainCat_id} )" class="glyphicon glyphicon-edit"></a>
<a ui-sref="deleteMainCategory( {mainCatId: mainCategory.mainCat_id} )" class="glyphicon glyphicon-minus-sign"></a>
</td>
</tr>
<tr>
<td ng-if="(!rows.length)" colspan="4" class="text-center">No results found.</td>
</tr>
</tbody>
</table>
<div tasty-pagination bind-items-per-page="showTCS.itemsPerPage" bind-list-items-per-page="showTCS.listItemsPerPage"></div>
</div>
I am working on an application in which I have different products with some other data associated with it in an html table with data binded using knockout js. The below code doesnot display products in sections but each product gets displayed as a different product though they are same.
HTML
<table class="productTable" data-bind="visible: !loading()">
<thead>
<tr>
<th>Product</th>
<th>Term</th>
<th>Location</th>
<th>Pipeline</th>
<th>Bid C/P</th>
<th>Bid Volume</th>
<th>Index</th>
<th>Bid</th>
<th>Offer</th>
<th>Offer Volume</th>
<th>Offer C/P</th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach: canadiancrudes" >
<tr >
<td data-bind="text:Product"></td>
</tr>
<tr>
<td data-bind="text: Term"></td>
<td data-bind="text: Location"></td>
<td data-bind="text: Pipeline"></td>
<td data-bind="text: BidCP"></td>
<td data-bind="text: BidVolume"></td>
<td data-bind="text: Index"></td>
<td>
<input type="text" id="txbReadBid" data-bind="value: Bid" /></td>
<td>
<input type="text" id="txbReadOffer" data-bind="value: Offer" /></td>
<td data-bind="text: OfferVolume"></td>
<td data-bind="text: OfferCP"></td>
<td></td>
<td>
<a href="#" title="Edit" data-bind="click: $root.edit">
<img src= '#Url.Content("~/Images/edit.png")' /></a></td>
<td><a href="#" title="Delete" data-bind="click: $root.remove">
<img src= '#Url.Content("~/Images/delete.png")' /></a></td>
<td>
<a href="#" title="Copy" data-bind="click: $root.copy">
<img src= '#Url.Content("~/Images/add.png")' /></a>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Product</th>
<th>Term</th>
<th>Location</th>
<th>Pipeline</th>
<th>Bid C/P</th>
<th>Bid Volume</th>
<th>Index</th>
<th>Bid</th>
<th>Offer</th>
<th>Offer Volume</th>
<th>Offer C/P</th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</tfoot>
</table>
From the below screen shot you can see that I have similar products with different other fields but they are not sectioned. Now I would like t have a section for each product like Product C5 has four entries in the table so, I want all of them in a single section and whenever I click on '+' image on the right it adds a row with same product associated with that '+' image and I am trying to add it to the same product section.
I have figured out a solution as follows
Index.cshtml
<!--ko foreach: products-->
<h3 data-bind="text: $data"></h3>
<table class="productTable">
<thead>
<tr>
<th>Term</th>
<th>Location</th>
<th>Pipeline</th>
<th>Bid C/P</th>
<th>Bid Volume</th>
<th>Index</th>
<th>Bid</th>
<th>Offer</th>
<th>Offer Volume</th>
<th>Offer C/P</th>
</tr>
</thead>
<tbody data-bind="foreach: $root.subsetcanadiancrudes.index.Product()[$data]">
<tr>
<td data-bind="text: Term"></td>
<td data-bind="text: Location"></td>
<td data-bind="text: Pipeline"></td>
<td data-bind="text: BidCP"></td>
<td data-bind="text: BidVolume"></td>
<td data-bind="text: Index"></td>
<td data-bind="text: Bid"></td>
<td data-bind="text: Offer"></td>
<td data-bind="text: OfferVolume"></td>
<td data-bind="text: OfferCP"></td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Term</th>
<th>Location</th>
<th>Pipeline</th>
<th>Bid C/P</th>
<th>Bid Volume</th>
<th>Index</th>
<th>Bid</th>
<th>Offer</th>
<th>Offer Volume</th>
<th>Offer C/P</th>
</tr>
</tfoot>
</table>
<!--/ko-->
Knockout JS
ko.observableArray.fn.extendsdistinct = function (attrib) {var me = this;me.index = {};me.index[attrib] = ko.observable({});ko.computed(function () {var attribIndex = {};ko.utils.arrayForEach(me(), function (item) {var key = ko.utils.unwrapObservable(item[attrib]);if (key) {attribIndex[key] = attribIndex[key] || [];attribIndex[key].push(item);}});me.index[attrib](attribIndex);});return me;};
var CanadianCrudeViewModel = function (CanadianContext) {
var self = this;
self.canadiancrudes = ko.observableArray();
self.products = ko.observableArray();
self.datainput = ko.observableArray();
self.loading = ko.observable(true);
self.subsetcanadiancrudes = ko.observableArray(self.datainput()).extendsdistinct('Product');
self.products = ko.computed(function () {
var products = ko.utils.arrayMap(self.subsetcanadiancrudes(), function (item) {
return item.Product;
})
return ko.utils.arrayGetDistinctValues(products).sort();
});
viewModel.canadiancrudes.push(obsCanadianCrude);
viewModel.subsetcanadiancrudes.push(obsCanadianCrude);
viewModel.canadiancrudes.sort(function (left, right) { return left.Product() === right.Product() ? 0 : (left.Product() < right.Product() ? -1 : 1) });