Handlebars - Passing data with each - handlebars.js

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 :)

Related

CSS pseudo-class: not (: first-child) on the tbody element

I'm trying to style all tbody tags except the first one but with poor results.
As you can see in the snippet, the style is applied to all elements, including the first one, where am I wrong?
div.cont_table_toggle table#general_list tbody.divider:not(:first-child) {
border-top: 8px solid red;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="cont_table_toggle">
<table id="general_list" class="table table-bordered">
<thead>
<tr>
<th>AAAA</th>
<th>BBBB</th>
</tr>
</thead>
<tbody id="block-1" class="divider">
<tr>
<td>1111</td><td>2222</td>
</tr>
</tbody>
<tbody id="block-2" class="divider">
<tr>
<td>3333</td><td>4444</td>
</tr>
</tbody>
<tbody id="block-3" class="divider">
<tr>
<td>5555</td><td>6666</td>
</tr>
</tbody>
</table>
</div>
Try using tbody.divider:not(:first-of-type).
The :first-of-type selector matches every element that is the first child, of a particular type, of its parent.
Reference : https://www.w3schools.com/cssref/sel_first-of-type.asp
https://www.w3schools.com/cssref/css_selectors.asp
Try it below.
div.cont_table_toggle table#general_list tbody.divider:not(:first-of-type) {
border-top: 8px solid red;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="cont_table_toggle">
<table id="general_list" class="table table-bordered">
<thead>
<tr>
<th>AAAA</th>
<th>BBBB</th>
</tr>
</thead>
<tbody id="block-1" class="divider">
<tr>
<td>1111</td><td>2222</td>
</tr>
</tbody>
<tbody id="block-2" class="divider">
<tr>
<td>3333</td><td>4444</td>
</tr>
</tbody>
<tbody id="block-3" class="divider">
<tr>
<td>5555</td><td>6666</td>
</tr>
</tbody>
</table>
</div>
tbody is not the first child of the table. So the :first-child selector does not work. If you remove the thead, it works.
div.cont_table_toggle table#general_list tbody.divider:not(:first-child) {
border-top: 8px solid red;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="cont_table_toggle">
<table id="general_list" class="table table-bordered">
<tbody id="block-1" class="divider">
<tr>
<td>1111</td><td>2222</td>
</tr>
</tbody>
<tbody id="block-2" class="divider">
<tr>
<td>3333</td><td>4444</td>
</tr>
</tbody>
<tbody id="block-3" class="divider">
<tr>
<td>5555</td><td>6666</td>
</tr>
</tbody>
</table>
</div>
You could use :not(#block-1), :nth-child(2), or as the other answer has suggested, :not(:first-of-type).
Use not(#block-1)
The first tbody has id that you can use. As you many know, id must unique.
tbody:not(#block-1) selects all tbodys except the first one.
#general_list tbody:not(#block-1) {
border-top: 8px solid red;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="cont_table_toggle">
<table id="general_list" class="table table-bordered">
<thead>
<tr>
<th>AAAA</th>
<th>BBBB</th>
</tr>
</thead>
<tbody id="block-1" class="divider">
<tr>
<td>1111</td><td>2222</td>
</tr>
</tbody>
<tbody id="block-2" class="divider">
<tr>
<td>3333</td><td>4444</td>
</tr>
</tbody>
<tbody id="block-3" class="divider">
<tr>
<td>5555</td><td>6666</td>
</tr>
</tbody>
</table>
</div>
Use :not(:nth-child(2))
#general_list tbody:not(:nth-child(2)) {
border-top: 8px solid red;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="cont_table_toggle">
<table id="general_list" class="table table-bordered">
<thead>
<tr>
<th>AAAA</th>
<th>BBBB</th>
</tr>
</thead>
<tbody id="block-1" class="divider">
<tr>
<td>1111</td><td>2222</td>
</tr>
</tbody>
<tbody id="block-2" class="divider">
<tr>
<td>3333</td><td>4444</td>
</tr>
</tbody>
<tbody id="block-3" class="divider">
<tr>
<td>5555</td><td>6666</td>
</tr>
</table>
</div>

Handlebar table createion with 3 inside each helper problem

Suppose i have 3 dummy array :
let dummyArray = [0,1,2,3,4];
let dummyArray2 = [0,1,2,3];
let dummyArray3 = [{data:'d1'},{data:'d2'}];
and i want create table with these array like this:
<table class="table">
<thead>
<tr>
<th>col-0</th>
<th>col-1</th>
<th>col-2</th>
<th>col-3</th>
<th>col-4</th>
</tr>
</thead>
<tbody>
{{#each dummyArray}}
<tr>
<td>row</td>
{{#each ../dummyArray2}}
<td>
{{#each ../../dummyArray3}}
{{this.data}}
{{/each}}
</td>
{{/each}}
</tr>
{{/each}}
</tbody>
</table>
but i get unexpected result, some cells in the table are empty.
Demo: https://jsfiddle.net/PouyaAk/m7g31e8y/32/
Use of #root is solving the problem, see below, however it's still intriguing to me why your code works that way - but I haven't used handelbarsjs for a quite while
<table class="table">
<thead>
<tr>
<th>col-0</th>
<th>col-1</th>
<th>col-2</th>
<th>col-3</th>
<th>col-4</th>
</tr>
</thead>
<tbody>
{{#each dummyArray}}
<tr>
<td>row</td>
{{#each #root.dummyArray2}}
<td>
{{#each #root.dummyArray3}}
{{this.data}}
{{/each}}
</td>
{{/each}}
</tr>
{{/each}}
</tbody>
</table>
Edit:
the code below fills only previously empty cells, leaving the rest of them empty
... strange
<tbody>
{{#each dummyArray}}
<tr>
<td>row</td>
{{#each ../dummyArray2}}
<td>
{{#each ../dummyArray3}}
{{this.data}}
{{/each}}
</td>
{{/each}}
</tr>
{{/each}}
</tbody>

Each cant run twice?

This is somehow a simple issue with handlebars where my TDs are not being rendered.
My Handlebar:
<table class="defaultTable" style="width:90mm;">
<colgroup>
{{#each cols}}
<col style="width:{{this.width}}mm;">
{{/each}}
</colgroup>
<tbody>
{{#each rows}}
<tr>
{{#each cols}}
<td>{{this.content}}</td>
{{/each}}
</tr>
{{/each}}
</tbody>
</table>
My Data:
cols = [{
width: 45,
content: ''
},{
width: 45,
content: ''
}];
Rows = [{},{}];
My Output
<table class="defaultTable" style="width:90mm;">
<colgroup>
<col style="width:45;">
<col style="width:45;">
</colgroup>
<tbody>
<tr>
</tr>
<tr>
</tr>
</tbody>
</table>
Why are the tds not being rendered? Did I miss something regarding how the each loop should work?
Thanks.
I was out of the context block indeed as the comment stated. It was searching for cols inside the rows object. Will post the fix so other ppl with the same issue can see, hope it helps someone.
<tbody>
{{#each rows}}
<tr>
{{#each ../cols}}
<td>{{this.content}}</td>
{{/each}}
</tr>
{{/each}}
</tbody>
The ../ on the cols solved it.

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)

Static row above knockout.js observable array table

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>

Resources