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.
Related
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 :)
I have a is-fullwidth Bulma table in my angular7 app which works fine. But now I need to add a angular component inside each row, and td tags lies inside that component. But when I do that, table rows not spans to its full width.
<table class="table is-fullwidth">
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of rows">
<app-table-row [details]="row">
</app-table-row>
</tr>
</tbody>
</table>
table-row.component.html
<td>
<div *ngIf="!showField"> {{ details.name }} </div>
<div *ngIf="showField" class="field">
<div class="control">
<input [value]="details.name" class="input" type="text">
</div>
</div>
</td>
<td>{{ details.address }}</td>
This outputs the following
if I remove the angular component and add tds normally, it spans correctly. Like this.
Why is it not work when angular component added? And how should I fix it?
The reason this is happening is probably because the td elements are not direct children of the tr, but children of the app-table-row component.
Not sure that it would make sense in your case, but you can change the selector property in the app-table-row component to select the tr itself, like so:
#Component({
selector: 'tr[app-table-row]',
...
})
export class AppTableRowComponent {}
And use it like this:
<table class="table is-fullwidth">
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of rows" app-table-row [details]="row">
</tr>
</tbody>
</table>
This way the app-table-row is not a separate node in the DOM.
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>
I have the following handlebars file:
<table>
<tbody>
{{#name_days}}
<tr>
<td class="name-days-country">
<span class="flag-sm flag-sm-{{flag}}"></span>
<span class="name-days-country-name">{{country}}</span>
</td>
<td class="name-day-dates">
{{#each months}}
<td class="name-days-tile">
<span>{{this}}</span>
</td>
{{/each}}
</td>
</tr>
{{/name_days}}
</tbody>
</table>
I'm expecting <td class="name-days-tile"> to be inside <td class="name-day-dates"> but it renders as:
<td class="name-day-dates"></div>
<td class="name-days-tile"></div>
Why isn't it rendering as expected?
The issue ended up being that one cannot put a td inside a td.
While one can manually do it, without it being valid in plain HTML, handlebars detected the issue and automatically applied a closing </td> before adding another opening <td> during the render process.
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>