Static row above knockout.js observable array table - data-binding

I have a html table and the rows come form an observable array....
<tbody data-bind="foreach: TableArray">
<tr>
<td data-bind:"text: Item1"></td>
etc....
How can I skip the first row... so I can add a static row (not a header) to the top of the table.
<tbody data-bind="foreach: TableArray">
<tr>
<td> Static Row </td>
</tr>
<tr>
<td data-bind:"text: Item1"></td>

The secret is in the containerless foreach markup. Check "Note 4" of the following link:
http://knockoutjs.com/documentation/foreach-binding.html
Here's a fiddle showing a basic example.
http://jsfiddle.net/internetH3ro/M9f4D/7/
Basic view model:
function ViewModel() {
var self = this;
self.items = [{
firstName: 'James',
lastName: 'McConnell'
},{
firstName: 'Scott',
lastName: 'Hanselman'
},{
firstName: 'Bill',
lastName: 'Gates'
}];
}
HTML markup:
<table>
<tr>
<th>First Name</th>
<th>Last Name</th>
</tr>
<!-- ko foreach: items -->
<tr>
<td><span data-bind="text: $data.firstName"></span></td>
<td><span data-bind="text: $data.lastName"></span></td>
</tr>
<!-- /ko -->
</table>
So you just wrap the content you want repeated in a comment, and Knockout will repeat that content for each element in your collection. Pretty nifty, I wish Angular had something like this.

One way to approach the issue would be to use Knockout's containerless binding syntax.
See Note 4 in Knockout's documentation of the foreach binding.
http://knockoutjs.com/documentation/foreach-binding.html
Javascript
var YourVM = function () {
this.allItems = ko.observableArray(["Fries", "Eggs Benedict", "Ham", "Cheese"]);
};
ko.applyBindings(new YourVM());
HTML
<table>
<thead>
<tr>
<th>Your Column</th>
</tr>
</thead>
<tbody>
<tr class="row-static">
<td>Static Row</td>
</tr> <!-- ko foreach: allItems -->
<tr>
<td data-bind="text: $data"></td>
</tr> <!-- /ko -->
</tbody>
</table>
Live example on JS Bin
http://jsbin.com/AzEwEce/1/edit

You could use an if binding to only output an extra row on the "first" pass.
Example:
<table data-bind ="foreach: rows">
<tr data-bind="if: $index() == 0" >
<td><span data-bind="text: $index"></span></td>
</tr>
<tr>
<td><span data-bind="text: text"></span></td>
</tr>
</table>

Related

Handlebars - Passing data with each

I am trying to center one of the td in table while each helper. Is it possible to do so?
Below is my code:
<table>
<thead>
<tr>
{{#each item.[0]}}
<th>{{#key}}</th>
{{/each}}
</tr>
</thead>
<tbody>
{{#each item}}
<tr>
<td>{{Name}}</td>
<td>{{Age}}</td>
</tr>
{{/each}}
</tbody>
</table>
I want it to be like this:
<thead>
<tr>
<th>Name</th>
<th style="text-align:center">Age</th>
</tr>
</thead>
<tbody>
<tr>
<td>User 1</td>
<td style="text-align:center">12</td>
</tr>
</tbody>
var theTemplateScript = $("#entry-template").html();
var theTemplate = Handlebars.compile(theTemplateScript);
var context = {
title: "My New Post",
body: "This is my first post!",
item: [{
"Name": "Ayyub",
"Age": 23
}]
};
console.log("context ", context)
var theCompiledHtml = theTemplate(context);
console.log("theCompiledHtml ", theCompiledHtml);
$('.content-placeholder').html(theCompiledHtml);
var html = theTemplate(context);
.Age {
text-align: center;
color: red;
}
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0/handlebars.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
</head>
<body>
<script id="entry-template" type="text/x-handlebars-template">
<table>
<thead>
<tr>
{{#each item.[0]}}
<th class="{{#key}}">{{#key}}</th>
{{/each}}
</tr>
</thead>
<tbody>
{{#each item}}
<tr>
<td>{{Name}}</td>
<td class="Age">{{Age}}</td>
</tr>
{{/each}}
</tbody>
</table>
</script>
<div class="content-placeholder">
<table>
<thead>
<tr>
{{#each item.[0]}}
<th class="{{#key}}">{{#key}}</th>
{{/each}}
</tr>
</thead>
<tbody>
{{#each item}}
<tr>
<td>{{Name}}</td>
<td class="Age">{{Age}}</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</body>
You can use this snippet, for reference I have added red color for font which you can remove later from the CSS file. Hope this helps :)

Real-Time Data-Binding

I have a table that displays a list of uploaded files. If I uploaded a file it needs to be reflected in the table. This is already happening — not, however, in real-time. I need to refresh the page to reflect the data that I need.
I tried refreshing the div in jquery but it is not working:
<div class="mjs-cell">
<div id="stipsData" data-bind="template:{name: 'rehash-customertab-stips-section', data: stipsViewModel}">
</div>
</div>
<div class="mjs-row">
<table class="table table-striped table-bordered">
<tr>
<th>Stip Name</th>
<th>Status</th>
<th>File Name</th>
</tr>
<tbody data-bind="foreach: $data">
<tr class="stips-row">
<td class="hidden stips-id" data-bind="text: StipulationTypeId"></td>
<td class="stips-text">
<a data-bind="text: StipulationType"></a>
</td>
<td class="stips-status">
<span data-bind="text: Status"></span>
</td>
<td class="stips-uploaded-file" data-bind="text: FileName"></td>
</tr>
</tbody>
</table>
</div>
Here is the code that I use for binding:
stipsViewModel = ko.computed(function () {
DealApiControllers.GetStipulations(dealId,
(response) => {
this.stipsViewModel = response.DealStipulationsDTOs;
},
(error) => {
console.error(error);
});
}, this);
For example the table shows Doc1, Doc2. If I upload Doc3 it should be reflected in the list.

Is it possible to select a set of table cells for CSS styling by row class and column selector

I have a web app containing a reporting module. The reporting module allows the user to select which fields they want to see (by name), and builds an array of data, which a mustache-style template processor turns into a table, with 1 column for each field.
The code behind, on the server, generates the data, including total and other "special" rows. These special rows are identified by adding a css class to the row.
I have just come across a requirement for a new type of "special" row, which requires underlining a particular field. I would prefer not to have special javascript just for this type of row, so I am wondering if there is a way to identify a cell (to underline it) in a stylesheet, given just a class attached to the row(s), and an id (or other identifier) attached to the column.
I realise I could do it using nth-child, but the columns are selected by the user, so the column number wouldn't be fixed.
Just to give you an idea, I have cooked up an example (the actual code is much more complicated, and uses a lot of library functions):
<table>
<thead>
<tr>
{{#each Columns}}<th id={{Id}}>{{Heading}}</th>{{/each}}
</tr>
</thead>
<tbody>
{{#each Rows}}
<tr class="{{Class}}>
{{#each Data}}<td>{{Value}}</td>{{/each}}
</tr>
{{/each}}
</tbody>
</table>
Typical data (number, content and order of columns varies according to user selection):
{
Columns: [
{ Id: "account", Heading: "Account" },
{ Id: "subAccountValueCP", Heading: "" },
{ Id: "valueCP", Heading: "Current Period" },
{ Id: "subAccountValueLP", Heading: "" },
{ Id: "valueLP", Heading: "Prior Period" }
],
Rows: [
{ Class: "heading", Data: [ "Income", "", "", "", "" ] },
{ Class: "normal", Data: [ "Consultancy", "", 5000.00, "", 4500.00 ] },
{ Class: "parent", Data: [ "Other", "", "", "", "" ] },
{ Class: "sub", Data: [ "Postage", "50.00", "", "45.00", "" ] },
{ Class: "sub", Data: [ "Packing", "50.00", "", "45.00", "" ] },
{ Class: "total", Data: [ "Other", "", 100.00, "", 90.00 ] }
]
}
Resulting table:
<table>
<thead>
<tr>
<th id="account">{{Heading}}</th>
<th id="subAccountValueCP">{{Heading}}</th>
<th id="valueCP">{{Heading}}</th>
<th id="subAccountValueLP">{{Heading}}</th>
<th id="calueLP">{{Heading}}</th>
</tr>
</thead>
<tbody>
<tr class="heading">
<td>Income</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="normal">
<td>Consultancy</td>
<td></td>
<td>5000.00</td>
<td></td>
<td>4500.00</td>
</tr>
<tr class="parent">
<td>Other</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="sub">
<td>Postage</td>
<td>50.00</td>
<td></td>
<td>45.00</td>
<td></td>
</tr>
<tr class="sub">
<td>Packing</td>
<td>50.00</td>
<td></td>
<td>45.00</td>
<td></td>
</tr>
<tr class="total">
<td>Other</td>
<td></td>
<td>100.00</td>
<td></td>
<td>90.00</td>
</tr>
</tbody>
</table>
Now, I want to style (e.g.) the cells in rows with class sub and column account with style padding-left: 20px;. As the order and content of columns is entirely user-defined, the only way I know of doing it is to place a class on every cell, and select on that class. However, I wondered if there was a suitable css selector which would select cells belonging to a particular column, other than by column number, as that would do the trick much more efficiently.
It appears it is not possible.
The only solution was to add a class to every cell in the relevant columns, and select on tr.rowclass td.colclass.
By adding a colgroup to the table, we can style columns.
From MDN:
The HTML Element (or HTML Table Column Group Element)
defines a group of columns within a table.
FIDDLE
.account,
.sub {
background: orange;
}
<table>
<colgroup class="account" />
<colgroup span="4" />
<thead>
<tr>
<th id="account">{{Heading}}</th>
<th id="subAccountValueCP">{{Heading}}</th>
<th id="valueCP">{{Heading}}</th>
<th id="subAccountValueLP">{{Heading}}</th>
<th id="calueLP">{{Heading}}</th>
</tr>
</thead>
<tbody>
<tr class="heading">
<td>Income</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="normal">
<td>Consultancy</td>
<td></td>
<td>5000.00</td>
<td></td>
<td>4500.00</td>
</tr>
<tr class="parent">
<td>Other</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="sub">
<td>Postage</td>
<td>50.00</td>
<td></td>
<td>45.00</td>
<td></td>
</tr>
<tr class="sub">
<td>Packing</td>
<td>50.00</td>
<td></td>
<td>45.00</td>
<td></td>
</tr>
<tr class="total">
<td>Other</td>
<td></td>
<td>100.00</td>
<td></td>
<td>90.00</td>
</tr>
</tbody>
</table>

Footable 2 Select rows

I'm using FOOTABLE to create job board. What I want to add is a checkbox option to select jobs (rows) so users can send cv to multiple jobs at once. Any idea on how to implement this in existing table?
simple example:
<table class="footable toggle-arrow" data-page-size="20" >
<thead>
<tr>
<th><!--select option id col--></th>
<th><span>Job Description</span></th>
<th><span>Area</span></th>
<th><span>Number</span></th>
<th><!--TYPE--></th>
<th><!--SEND--></th>
</tr>
</thead>
<tbody>
<tr><!---JOB-->
<td><input type="checkbox" value="id"></td>
<td>job description value</td>
<td>area value</td>
<td>job number</td>
<td data-value="4566">4566</td>
<td data-value="3"><img title="hot" src="vip.png" /></td>
<td></td>
</tr><!---END JOB-->
</tbody>
Thanks!
Here's a quick example of one way you could do this:
<!DOCTYPE html>
<html>
<head>
<script data-require="jquery#*" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<a id="sendSelectedButton" href="#">Send Selected</a>
<table id="theTable">
<thead>
<tr>
<th></th>
<th>Description</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input type="checkbox">
</td>
<td>Job 1</td>
<td>send
</td>
</tr>
<tr>
<td>
<input type="checkbox">
</td>
<td>Job 2</td>
<td>send
</td>
</tr>
<tr>
<td>
<input type="checkbox">
</td>
<td>Job 3</td>
<td>send
</td>
</tr>
</tbody>
</table>
<script>
function sendRows(rows) {
if (rows === undefined ||
rows === null ||
rows.length === 0)
return;
//Do stuff to send rows here.
}
$(document).ready(function() {
$("#sendSelectedButton").on("click", function() {
var checkRows = $("#theTable").find("tbody tr").has("input:checked");
sendRows(checkRows);
});
$("table").on("click", "tr a", function() {
var row = $(this).parents("tr");
sendRows(row);
});
});
</script>
</body>
</html>
Here's a plunk with the same code: http://plnkr.co/edit/tK4WpCvV7vSjVFmKlJIx
I didn't add any Footable here because it doesn't seem like that Footable will affect it one way or another.
I think you'll find that things quickly get a lot more complex as your application matures. I'd suggest you look some type of data binding. I personally use Knockout.js. Even if you don't decide to use Knockout.js, I think their tutorial is pretty cool. (http://knockoutjs.com/index.html)

issue with css inherit and Ajax

There is a table alt text that uses CSS (by using inherit in CSS) to format its layout. As you can see there is a drop down on top of the window that allows us select names, and based on the selection, the table would be populated. This action has been handled by an Ajax call, so we only refresh the table and not the rest of the page. However, when we call this Ajax call, even though we don't have any change in the code, there would be an extra space between vertical and horizontal borders of this table. I assume that there is a problem with the Ajax call and the CSS layout that we have this extra spaces. Does it make sense? or Do you any place that I can start my investigations?
Here is the source code of my Test.jsp
<a:test-webpart>
<table class="ContentPanel first-child" cellspacing="0" cellpadding="0">
<tr>
<th id="title" class="CPHeader" width="100%" colspan="400" style="border-bottom:1px solid <theme:get selector="#test .DefaultBorder" attribute="border-color" />;"><c:out value="${tile_title}" /></th>
</tr>
<%# include file="MyTest.jst" %>
<tbody class="content-area">
<tr>
<td>
<table class="ContentPanel ControlLayout" >
<tr>
<th style="padding-left:7px;" width="20%"><label for="testlist"><span >*</span><fmt:message key = "jsp.request.testlist" bundle="${local}" /></label></th>
<td class="last-child" width="80%">
<span >
<html:select property="valueAsMap(test_ITEM).value(test_OFFER)" styleClass="dropDown" styleId="offeredtest">
<html:optionsCollection property="value(Item_test_LIST)" label = "name" value ="id" />
</html:select>
</span>
</td>
</tr>
<tr>
<th style="padding-left:7px;" width="20%"><label for="employeeslist"><span >*</span><fmt:message key = "jsp.reques.employeeslist" bundle="${local}" /></label></th>
<td class="last-child" width="80%" >
<span >
<html:select property="valueAsMap(test_ITEM).value(Item_test_EMP)" onchange="javascript:getAlltests()" styleClass="dropDown" styleId="employeeId">
<html:optionsCollection property="value(Item_test_EMP_LIST)" label = "name" value = "id" />
</html:select>
</span>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<th style="padding-left:7px;" align="left"><label for="testacceptlist"><span >*</span><fmt:message key = "jsp.request.testacceptlist" bundle="${local}" /></label></th>
</tr>
<tr>
<td style="padding-left:7px;">
<kvl:rsr-webpart>
<div id="testsTable">
<table class="Tabular" width="100%" cellpadding="0" cellSpacing="0">
<tr class="first-child">
<th><fmt:message key = "jsp.request.select" bundle="${local}" /></th>
<th ><fmt:message key = "jsp.request.a" bundle="${local}" /></th>
<th ><fmt:message key = "jsp.request.b" bundle="${local}" /></th>
<th ><fmt:message key = "jsp.request.c" bundle="${local}" /></th>
<th ><fmt:message key = "jsp.request.d" bundle="${local}" /></th>
<th ><fmt:message key = "jsp.request.e" bundle="${local}" /></th>
<th ><fmt:message key = "jsp.request.f" bundle="${local}" /></th>
<th class="last-child"><fmt:message key = "jsp.request.job" bundle="${local}" /></th>
</tr>
<c:forEach var="item" items = "${items}" varStatus="status">
<tr class="<c:if test='${status.index % 2 != 0}'>Even</c:if> <c:if test='${item.isFromPrimaryJob == true}'>Primary</c:if> <c:if test='${item.isFromPrimaryJob != true}'>Exchange</c:if>">
<td>
<input type="checkbox"
id="test_id_<c:out value="${item.id}"/>_<c:out value="${item.Date}"/>"
name="value(test_selected)"
value="<c:out value="${item.id}" />_<c:out value="${item.Date}"/>"
onclick="javascript:checkBox('test_id_<c:out value="${item.id}"/>_<c:out value="${item.Date}"/>','value(test_selected)','valueAsMap(REQUEST_ITEM).value(test_selected_list)','false')" >
</td>
<td>
<c:choose>
<c:when test="${empty item.label}">
</c:when>
<c:otherwise>
<c:out value="${item.label}"/>
</c:otherwise>
</c:choose>
</td>
<td><c:out value="${item.Date}"/></td>
<td><c:out value="${item.b}"/></td>
<td><c:out value="${item.d}"/></td>
<td><c:out value="${item.e}"/></td>
<td><c:out value="${item.f}"/></td>
<td class="last-child"><c:out value="${item.job}"/></td>
</tr>
</c:forEach>
</table>
</div>
</kvl:rsr-webpart>
</td>
</tr>
<tr>
<td style="padding-left:7px;">
<table class="ContentPanel ControlLayout" width="100%">
<%# include file="request.jst" %>
</table>
</td>
</tr>
</tbody>
</table>
</a:test-webpart>
have a look at the generated HTML. just looking at the rendered stuff won't help except to something is wrong, not what. and just looking at the server code won't help as it uses magic and hides the HTML sometimes.
Later on I figured out that the problem has nothing to do with the any Ajax rendering. It was the return HTML tag that had these extra padding as it was inheriting its layout from another place. I enforced my padding and borderline along with cells that I was sending from server and everything worked like a charm.

Resources