Using knockout if binding inside a table - javascript

I was trying to use the if binding inside a table and the 3rd column is not at all displaying the text where as the entries in the 1st column are getting displayed.
<table id="searchPanelForm" cellspacing="0" cellpadding="0" align="center" class="conttable" width="100%" border="0" data-bind="">
<tbody>
<!-- ko foreach: searchPanelArray -->
<!-- ko if: $parent.isSearchEven($data.id) -->
<tr>
<td class="col2" data-bind="text: $data.label"></td>
<td class="col3"><input type="text"></td>
<!-- /ko -->
<!-- ko if: !$parent.isSearchEven($data.id) -->
<td class="col2" data-bind="text: $data.label"></td>
<td class="col3"><input type="text"></td>
</tr>
<!-- /ko -->
<!-- /ko -->
</tbody>
</table>
searchPanelArray is populated through an ajax call and isSearchEven returns true or false when the index is even or odd respectively.

Knockout expects "containerless control flow syntax" to act like elements. They cannot start on the outside of an element and end inside the element. So from Knockout's point of view, the comments internal to <tr> are simply malformed and ignored. So this is what it looks like for Knockout:
<!-- ko foreach: searchPanelArray -->
<!-- ko if: $parent.isSearchEven($data.id) -->
<tr>
<td class="col2" data-bind="text: $data.label"></td>
<td class="col3"><input type="text"></td>
<td class="col2" data-bind="text: $data.label"></td>
<td class="col3"><input type="text"></td>
</tr>
<!-- /ko -->
<!-- /ko -->
Logically, you want to group every two items in your array. You should create a computed observable the returns a new array with the two items grouped together.
this.searchPanelArrayGrouped = ko.pureComputed(function() {
var result = [], source = this.searchPanelArray();
for (var i = 0; i < source.length; i += 2) {
if (i + 1 >= source.length) {
result.push({left: source[i], right: {}});
} else {
result.push({left: source[i], right: source[i+1]});
}
}
return result;
}, this);
Html:
<!-- ko foreach: searchPanelArrayGrouped -->
<tr>
<td class="col2" data-bind="text: $data.left.label"></td>
<td class="col3"><input type="text"></td>
<td class="col2" data-bind="text: $data.right.label"></td>
<td class="col3"><input type="text"></td>
</tr>
<!-- /ko -->
https://jsfiddle.net/bg75xvxc/
Here is a related answer: https://stackoverflow.com/a/10577599/1287183

Related

Collapsible data row with dynamic values

Context: There are a set of months in a table (e.g. May, Jun, July) and under those months will be all of the readings for the given month.
The code:
<tbody data-bind="visible: !MeterReadingHistory_IsBusy(), foreach: HeaderLines()" style="display: none">
<tr data-toggle="collapse" data-target=".order1">
<td>
<!-- ko if: meterReadings.length > 0-->
<span class="glyphicon glyphicon-chevron-down"></span>
<span class="reading-history-data" data-bind="html: monthName"></span>
<!-- /ko -->
<!-- ko if: meterReadings.length == 0-->
<span class="reading-history-data" data-bind="html: monthName"></span>
<!-- /ko -->
</td>
<td>
<span class="reading-history-data" data-bind="html: latestReadingDate"></span>
</td>
<td>
<span class="reading-history-data" data-bind="html: latestReadingType"></span>
</td>
<td>
<span class="reading-history-data" data-bind="html: latestReadingElectric"></span>
</td>
<td>
<span class="reading-history-data" data-bind="html: latestReadingGas"></span>
</td>
</tr>
<!-- ko if: meterReadings.length > 0 -->
<tr class="collapse order1" >
<td colspan="5">
<table class="table mb-none desktop-only">
<thead>
<tr>
<th>Day</th>
<th>Reading Source</th>
<th>Electricity</th>
<th>Gas</th>
</tr>
</thead>
<tbody>
<!-- ko foreach: meterReadings -->
<tr>
<td data-bind="text: readingDateParsed"></td>
<td data-bind="html: readingType"></td>
<!-- ko foreach: readings -->
<td data-bind="html: reading"></td>
<!-- /ko -->
<!-- ko if: readings.length == 0 -->
<td></td>
<td></td>
<!-- /ko -->
<!-- ko if: readings.length == 1 -->
<td></td>
<!-- /ko -->
</tr>
<!-- /ko -->
</tbody>
</table>
</td>
</tr>
<!-- /ko -->
</tbody>
The problem: When i click on any of the rows, it expands every month row exposing all of the data when in fact i only want to display the sub-rows for the actual month that has been clicked.
The main problem is that this table is dynamic, and we wont know how many header rows will be produced, therefore it will be difficult to assign each row to a specific data source via the data-bind attribute.
So......how can I get this code to display only the row of data that I have clicked on, e.g. May, and display all the readings for this given month while all of the other header rows remain closed?
Thanks!
$([data-toggle="collapse"]).on('click',function(){
var thisCollapse = $(this).attr('data-target');
$(thisCollapse).slideToggle('slow');
})

Hiding table rows with checkbox [duplicate]

This question already has answers here:
jQuery ID selector works only for the first element
(7 answers)
Closed 6 years ago.
I'm trying to hide table rows when a tickbox is checked. I have managed to get it working, but it will only hide the first instance of the id. Could someone direct me in to changing the js so it will hide all with matching id.
JSFIDDLE
$(document).ready(function() {
$('#checkbox1').change(function() {
if (!this.checked)
$('#tierPoints').fadeIn('slow');
else
$('#tierPoints').fadeOut('slow');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td colspan=2>
<input type="checkbox" id="checkbox1">Show/Hide</td>
</tr>
<!-- End Of Row -->
<tr id="tierPoints">
<td>71</td>
<td>1000</td>
</tr>
<!-- End Of Row -->
<tr id="tierPoints">
<td>73</td>
<td>2000</td>
</tr>
<!-- End Of Row -->
<tr id="tierPoints">
<td>75</td>
<td>3000</td>
</tr>
<!-- End Of Row -->
</table>
In HTML, an id has to be unique. See www.w3.org... for more details.
Try to change id="tiersPoints" to class="tiersPoints".
You need to use the "class" selector instead of ID Selector and the ID needs to be unique. You can have multiple elements with same Class Name.
$(document).ready(function() {
$('#checkbox1').change(function() {
if (!this.checked)
$('.tierPoints').fadeIn('slow');
else
$('.tierPoints').fadeOut('slow');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td colspan=2>
<input type="checkbox" id="checkbox1">Show/Hide</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td>71</td>
<td>1000</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td>73</td>
<td>2000</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td>75</td>
<td>3000</td>
</tr>
<!-- End Of Row -->
</table>
You need to have unique ids. Use classes in this case:
$(document).ready(function() {
$('#checkbox1').change(function() {
if (!this.checked)
$('.tierPoints').fadeIn('slow');
else
$('.tierPoints').fadeOut('slow');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td colspan=2>
<input type="checkbox" id="checkbox1">Show/Hide</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td>71</td>
<td>1000</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td>73</td>
<td>2000</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td>75</td>
<td>3000</td>
</tr>
<!-- End Of Row -->
</table>
An id should be distinct within your page.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td colspan=2>
<input type="checkbox" id="checkbox1">Show/Hide</td>
</tr>
<!-- End Of Row -->
<tr id="tierPoints1">
<td>71</td>
<td>1000</td>
</tr>
<!-- End Of Row -->
<tr id="tierPoints2">
<td>73</td>
<td>2000</td>
</tr>
<!-- End Of Row -->
<tr id="tierPoints3">
<td>75</td>
<td>3000</td>
</tr>
<!-- End Of Row -->
</table>
Here is solution:
As i mentioned in comment : You need to use tierPoints class. You cannot you multiple tr with same id
$(document).ready(function () {
$('#checkbox1').change(function () {
if (!this.checked)
$('.tierPoints').fadeIn('slow');
else
$('.tierPoints').fadeOut('slow');
});
});
input[type=checkbox]{padding:0; margin:0;}
td, th {
background: #ddd;
color: #000;
padding: 2px 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td colspan=2><input type="checkbox" id="checkbox1">Show/Hide</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td>71</td>
<td>1000</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td>73</td>
<td>2000</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td >75</td>
<td>3000</td>
</tr>
<!-- End Of Row -->
</table>
Try this. Change id by class. Id is unique by definition.
$(document).ready(function() {
$('#checkbox1').change(function() {
if (!this.checked)
$('.tierPoints').fadeIn('slow');
else
$('.tierPoints').fadeOut('slow');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td colspan=2>
<input type="checkbox" id="checkbox1">Show/Hide</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td>71</td>
<td>1000</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td>73</td>
<td>2000</td>
</tr>
<!-- End Of Row -->
<tr class="tierPoints">
<td>75</td>
<td>3000</td>
</tr>
<!-- End Of Row -->
</table>

loop through observable array of knockout property

I am using knockout mapping library to bind JSON data from .NET service to a property in KO view model, in which the property has an array of objects that I need to loop through and render on the screen.
The .NET model:
new{
count = count,
total = total,
rows = items,
}
the rows property holds list of objects, which needs to be rendered into a table using KO.
I tired using
<!-- ko foreach: masterData().rows-->
<tr>
<td><span data-bind='text: Id' /></td>
<td><span data-bind='text: Name' /></td>
<td><span data-bind='text: Description' /></td>
<td><span data-bind='text: Status' /></td>
</tr>
<!-- /ko -->
where the masterData is an observable. After data load, it renders nothing inside the table. As a workaround, I have changed the model the observable to observableArray([])
new List<dynamic> {
new
{
count = recCount,
total = total,
rows = items,
}};
and changed the rendering logic to
<!-- ko foreach: masterData -->
<!-- ko foreach: rows-->
<tr>
<td><span data-bind='text: Id' /></td>
<td><span data-bind='text: Name' /></td>
<td><span data-bind='text: Description' /></td>
<td><span data-bind='text: Status' /></td>
</tr>
<!-- /ko -->
<!-- /ko -->
Now it works as expected. There should be a better way of dealing with this or I am missing something I suppose. Also, I needed to loop through this list in order to access other properties.
EDIT 1:
http://jsfiddle.net/krishnasarma/hdt9ehth/
well i tweaked your code little bit to make it ideal . I see not point looping masterData for getting rows data .
we can now use with binding which is perfect for such scenario stated above.
view:
<table>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Description</th>
<th>Status</th>
</tr>
</thead>
<tbody data-bind="with:masterData2">
<!-- ko foreach:rows -->
<tr>
<td><span data-bind='text: Id' /></td>
<td><span data-bind='text: Name' /></td>
<td><span data-bind='text: Description' /></td>
<td><span data-bind='text: Status' /></td>
</tr>
<!-- /ko -->
</tbody>
</table>
viewModel:
var VM = {
masterData: ko.observable([]), //initializing
masterData2: ko.observable([])
}
sample working fiddle here
If you want to in a Lazy Loading way check here

If statement in knockout.js not working as expected

I'm trying to display the string "No data was found." inside a table row whenever the data array is empty, but it seems the message get always printed no matter what.
Reproduction online (ignoring the condition orders.length ==0)
What am I doing wrong?
<table>
<thead>
<tr>
<th>Truck</th>
<th>Pickup</th>
</tr>
</thead>
<!-- ko if: orders.length==2 -->
<tbody>
<tr colspan="2">No data was found.</tr>
</tbody>
<!-- /ko -->
<tbody data-bind="foreach: orders">
<tr>
<td data-bind="text: truck"></td>
<td></td>
</tr>
</tbody>
</table>
If your orders is an ko.observableArray you need to write orders() to get the underlying array and get the length from there:
<!-- ko if: orders().length== 0 -->
Your HTML also invalid, the td elements are missing from:
<!-- ko if: orders().length==0 -->
<tbody data-bind="if: orders().length==0">
<tr colspan="2"><td>No data was found.</td></tr>
</tbody>
<!-- /ko -->
Demo JSFiddle.

Fomatting labels on Y-axis in Highcharts with Data from HTML table

Please, I'm stuck here trying to format the Y-axis in Highcharts so it indicates currency symbol but mainly, i need the unit abbreviations to show. Here is my Html and javascript. It gets data from an HTML table.
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script src="jquery-1.9.0.min.js"></script>
<script src="highcharts.src.js"></script>
<script src="jquery.highchartTable.js"></script>
<script>
$(document).ready(function() {
$('table.highchart').highchartTable();
});
</script>
</head>
<body>
<table class="table table-bordered table-condensed table-striped table-primary table-vertical-center checkboxs highchart" data-graph-container-before="1" data-graph-type="column" data-graph-yaxis-1-formatter-callback="graph_ValueFormatter" data-graph-height="350">
<thead>
<tr>
<th data-graph-hidden="1">Location</th>
<th class="center" style="width: 100px;">Sales</th>
<th class="center" style="width: 100px;">Pipeline</th>
<th class="center" style="width: 100px;">Projected</th>
</tr>
</thead>
<tbody>
<!-- Item -->
<tr class="selectable">
<td><strong>Africa Re, VI Lagos</strong></td>
<td class="center">31,977</td>
<td class="center">1,230</td>
<td class="center">31,977</td>
</tr>
<!-- // Item END -->
<!-- Item -->
<tr class="selectable">
<td><strong>Muliner Towers, Ikoyi Lagos</strong></td>
<td class="center">28,756</td>
<td class="center">1,079</td>
<td class="center">28,835</td>
</tr>
<!-- // Item END -->
<!-- Item -->
<tr class="selectable">
<td><strong>Somewhere, London</strong></td>
<td class="center">13,328</td>
<td class="center">1,833</td>
<td class="center">14,161</td>
</tr>
<!-- // Item END -->
<!-- Item -->
<tr class="selectable">
<td><strong>Somewhere, Johanesburg</strong></td>
<td class="center">38,893</td>
<td class="center">3,430</td>
<td class="center">38,893</td>
</tr>
<!-- // Item END -->
<!-- Item -->
<tr class="selectable">
<td><strong>Someplace, Nairobi</strong></td>
<td class="center">241,178</td>
<td class="center">2,247</td>
<td class="center">243,425</td>
</tr>
<!-- // Item END -->
</tbody>
</table>
</body>
</html>![enter image description here][1]
You can use formatter in yAxis labels: http://api.highcharts.com/highcharts#yAxis.labels.formatter

Categories

Resources