Mustache Template with Nested Array of Objects - javascript

Could use a little help figuring out why my Mustache template isn't rendering properly. I'm very confused why the following isn't working. I'm sure it's a minor stupid mistake of mine or something...
var tableRows = [
{name: 'name1',
values: ['1','2','3']},
{name: 'name2',
values: ['1','2','3']},
{name: 'name3',
values: ['1','2','3']}
];
var template = $('#mustache-template').html();
$('#target').append(Mustache.render(template, {rows: tableRows}));
HTML Template:
<div id="mustache-template">
<table>
<tbody>
{{#rows}}
<tr class="">
<td>{{name}}</td>
{{#values}}
<td>{{.}}</td>
{{/values}}
</tr>
{{/rows}}
</tbody>
</table>
</div>
I'm expecting a table with each array item being its own row, but instead I'm getting this:
[object Object]
Here's a jsFiddle to illustrate: http://jsfiddle.net/gF9ud/

The problem is that the browser handles your template as an invalid table element. It's not a good idea to store your templates on a page like that, use <script type="text/template"> to wrap them:
<script id="mustache-template" type="text/template">
<table>
{{#rows}}
<tr class="">
<td>{{name}}</td>
{{#values}}
<td>{{.}}</td>
{{/values}}
</tr>
{{/rows}}
</table>
</script>
http://jsfiddle.net/zHkW5/

Another solution that I found works is to comment out the mustache like so:
<div id="mustache-template">
<table>
<tbody>
<!-- {{#rows}} -->
<tr class="">
<td>{{name}}</td>
{{#values}}
<td>{{.}}</td>
{{/values}}
</tr>
<!-- {{/rows}} -->
</tbody>
</table>
</div>
For me, it rendered exactly as I had hoped. I think the browser kind of freaks seeing code between tr tags.

Related

dynamic handlebar table creation

i cant dynamically create table using handlethe bars. "arrays" is an array of objects (each object has id, name, description, and category).
I dont know why the code below worked for li element insertion but not for table. Can some one help?
let arrays = [{ id: 0, name: "name0", description: "this is is name0","category":1} ,{ id: 1, name: "name1", description: "this is is name1","category":2},...]
let template =Handlebars.compile($('#template1').html())
let html = template({arrays: arrays})
$('#div1').append(html)
<template id="template1">
<table>
<thead>
<tr>
<th>ID</th>
<th>name</th>
<th>description</th>
</tr>
</thead>
<tbody>
{{#each arrays}}
<tr>
<td>{{id}}</td>
<td>{{name}}</td>
<td>{{desciption}}</td>
</tr>
{{/each}}
</tbody>
</table>
</template>
the expectation is a table with just id name and description but not category
you're trying to insert a template after having processed the compiling. Your template won't work except for the parts that are not related to handlebars. If you want to process the template once you've done the insert in your HTML file then try to do your template compiling after the append and not before.
Usually I use jquery $(document).ready(...) to do such delaying.

ng-repeat issue with JSON Object

So I'm trying to print the keys and values of a simple JSON object inside an HTML table with ng-repeat but not able to print it on the html page. The JSON object has been received from the backend and am trying to populate that in the frontend. I understand that I am doing a silly mistake somewhere but can't understand where.
JSON Object
json_data ={
user1 : "matt",
user2 : "kim",
user3 : "Tim"
}
$scope.rows = json_data;
HTML code..
<table ng-if="displayTable">
<caption>Results</caption>
<tr>
<th>Username</th>
<th>Name</th>
</tr>
<tr ng-repeat="(key, value) in rows">
<td> {{key}} </td> <td> {{ value }} </td>
</tr>
</tr>
</table>
Can't understand what silly mistake I am doing here.
Try {{rows.key}} and {{rows.value}}. Although I don't thing this is the answer. Give it a try..
Alternative ly you can try to see if it works with just one , either key or value...
First at all, the (key, value) is more well represented by (index, value).
A correct version of this piece of code will output this:
0 {"user1":"matt","user2":"kim","user3":"Tim"}
which 0 is the first index of an array and the json is the entire value.
So, i guess you are using a bad approach.
Try to modify your array to something like that:
$scope.rows = [
{key: 'user1', user: 'matt'},
{key: 'user1', user: 'kim'},
{key: 'user1', user: 'Tim'},
];
And modify your HTML to:
<table ng-if="displayTable">
<caption>Results</caption>
<tr>
<th>Username</th>
<th>Name</th>
</tr>
<tr ng-repeat="row in rows">
<td> {{row.key}} </td> <td> {{ row.user }} </td>
</tr>
</tr>
</table>

Loop through array in array with Angular

Working on a TODO-app to learn Angular. I have this hardcoded array as a "database" and i want to display the tasks in the view.
var taskLists = [
{name: 'Todays todo', id: '1', tasks:['Make coffe', 'another task']},
{name: 'Tomorrow i will do this', id: '2', tasks:['Code well', 'go to bed']}
];
So how do i iterate through an array inside an array in an angular-view?
I tried to have two ng-repeats but cant get it to work right. I want to display the tasks one by one as <td>, not just the whole tasks array as one <td> as it does right now ['Make coffe', 'another task']
This is what the view looks like.
<h2 ng-repeat="object in list">{{object.name}}</h2>
<table>
<thead>
<tr>Tasks</tr>
</thead>
<tr>
<td ng-repeat="task in list">{{task.tasks}}</td>
</tr>
</table>
You have a problem in your logic.
Fist your HTML tag from child must be inside the parent.
<div class="parent" ng-repeat="object in list">
<h2>{{object.name}}</h2>
<table>
<thead>
<tr>Tasks</tr>
</thead>
<tr ng-repeat="task in object.tasks">
<td>{{item}}</td>
</tr>
</table>
</div>
Try this and check if it works.

ng-switch inside ng-repeat not working

I have data that basically boils down to this:
function ExampleCtrl($scope) {
$scope.myData= [
{text: "blah", other: 3, V: 'caseOne'},
{text: "blah", other: 3, V: 'caseTwo'},
{text: "blah", other: 3, V: 'caseThree'}
];
}
This is being used like this:
<div ng-controller="ExmapleCtrl">
<table>
<tr>
<td>Text</td>
<td>Other</td>
<td>V</td>
</tr>
<tr ng-repeat="data in myData">
<td>{{data.text}}</td>
<td>{{data.other}}</td>
<td ng-switch on="data.V">
<td ng-switch-when="caseOne"><img src="assets/img/pass.png"/></td>
<td ng-switch-when="caseTwo"><img src="assets/img/pass.png"/></td>
<td ng-switch-when="caseThree"><img src="assets/img/fail.png"/></td>
</td>
</table>
</div>
The problem is is that I am getting this error:
Error: No controller: ngSwitch..
I clearly have set the controller to ExampleCtrl, I don't see any typing errors, so I am at a loss unfortunately.
I believe the issue has to do with the ng-switch producing invalid markup. I'm not sure you can nest a td inside another td. Anyways, if you change it to this it will work:
<td ng-switch on="data.V">
<img src="assets/img/pass.png" ng-switch-when="caseOne"/>
<img src="assets/img/pass.png" ng-switch-when="caseTwo"/>
<img ng-switch-when="caseThree" src="assets/img/fail.png"/>
</td>
Here is a working demo: http://plnkr.co/edit/zUdkJYfnlJul6HsyCGfZ
I'll go ahead and suggest a couple more solutions that don't use a switch that might be a little nicer. Check out the last two td's
<tr ng-repeat="data in myData">
<td>{{data.text}}</td>
<td>{{data.other}}</td>
<td>
<img src='assets/img/{{data.V}}.png' /> <!-- assuming you have an image with name caseOne.png/caseTwo.png/etc -->
</td>
<td>
<img src='{{passFail[data.V]}}' /> <!-- transform the case stuff to pass/fail based on some business rules, this is an object but could be a function-->
</td>
</tr>
$scope.passFail = {
'caseOne' : 'assets/img/pass.png',
'caseTwo' : 'assets/img/pass.png',
'caseThree' : 'assets/img/fail.png'
};
An add-on to the above answer
Incase if there is just plain text inside td like switch casing user roles or something, you can add a span tag inside the td to contain the text
<td ng-switch="role">
<span ng-switch-when="1">Administrator</span>
<span ng-switch-when="2">Moderator</span>
</td>

Dust.js and tables

I am new to Dust.js and am trying to iterate a JSON object with records and render each of them into a row within a table. Below is the script, I am using to render the table, but am running into issues, I guess while rendering, especially the template argument of the render function. Appreciate if I could be pointed in the right direction
<div id="dustPlaceholder"></div>
<script id="goalTemplate">
<table id="dustGoals">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
{#friends}
<tr>
<td>{name}</td>
<td>{age}</td>
</tr>
{/friends}
</tbody>
</table>
</script>
</div>
<script type="text/javascript">
var src = document.getElementById("goalTemplate").innerHTML;
var compiled = dust.compile(src);
dust.render("goalTemplate", { friends: [ { name: "Moe", age: 37}]},
function(err, out) {
document.getElementById('dustPlaceholder').innerHTML = out;
});
</script>
You need to include the entire Dust.js library if you are going to be rendering on the client, so you need to include the dust-full-0.3.0.min.js. Additionally,
<script src="dust-full-0.3.0.min.js"></script>
Also, what is "goalTemplate"?
Also what are you compiling? There are no variables in there. You need to compile the actual HTML - the content in the DIV tag. So everything including the div tags belong in the src variable.
Also, you must assume a name to the compiled template so it can be accessed. I'm really confused what you were doing before, but this example should work:
<script src="dust-full-0.3.0.min.js"></script>
<script type = "text/javascript">
var source = "<div id="dustPlaceholder"></div>
<script id="goalTemplate">
<table id="dustGoals">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
{#friends}
<tr>
<td>{name}</td>
<td>{age}</td>
</tr>
{/friends}
</tbody>
</table>
</script>
</div>";
var compiled = dust.compile(src, goalTemplate);
dust.render("goalTemplate", { friends: [ { name: "Moe", age: 37}]},
function(err, out) {
document.getElementById('dustPlaceholder').innerHTML = out;
});
</script>

Categories