mustache js - Can't access array value using tables - javascript

I am having a problem with Mustache.js accessing to the values of a json array and I need some help.
The problem is when I want to access to the values using a table. It always shows [object Object], when it should show the array content.
Below is a working and a non-working example:
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://raw.github.com/janl/mustache.js/0.7.2/mustache.js"></script>
</head>
<body>
<div id="template" style="display:none">
<p>Works but not what I need:</p>
<p>{{#numbers}} {{.}} {{/numbers}} </p>
<p>Doesn't work:</p>
<table>
<tr>
{{#numbers}} <th> {{.}} </th> {{/numbers}}
</tr>
</table>
</div>
<div id="rendered"></div>
<script>
var json = {
"numbers": [ 1, 2, 3 ]
};
var compiledTemplate = Mustache.to_html($('#template').html(), json).replace(/^\s*/mg, '');
$('#rendered').html(compiledTemplate);
</script>
</body>
</html>
Output is:
Works but not what I need:
1 2 3
Doesn't work:
[object Object]
Is there any way to solve this problem or to print the object attributes using mustache.js?
The issue was already asked in their issue system, no replies yet:
https://github.com/janl/mustache.js/issues/295
Thanks,
Mariano.

Finally, this is what I did.
Replaced the div element template, to a script element:
from <div id="template" style="display:none"> to <script id="template" type="text/x-mustache-template">
And worked as expected =)

Would you like this?
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://raw.github.com/janl/mustache.js/0.7.2/mustache.js"></script>
</head>
<body>
<div id="template" style="display:none">
<p>Works but not what I need:</p>
<p>{{#numbers}} {{.}} {{/numbers}} </p>
<p>Doesn't work:</p>
<table>
<tr>
{{#numbers}} {{{th}}} {{/numbers}}
</tr>
</table>
</div>
<div id="rendered"></div>
<script>
var json = {
"numbers": [ 1, 2, 3 ],
"th": function () {
return "<th>" + this + "</th>"
}
};
var compiledTemplate = Mustache.to_html($('#template').html(), json);
$('#rendered').html(compiledTemplate);
</script>
</body>
</html>

I spent a lot of time debugging this.
The problem is $('#template').html(). It returns broken HTML because table markup is malformed (stuff outside <th> is rendered outside the table by browser)
That is why changing to <script> helps

Related

Imported Excel data in HTML Table is Undefined

I'm making a web page with a table that reads excel files. Following this example here: https://www.youtube.com/watch?v=OK60UdWyUdE. In this project, I use angular, jQuery, HTML, and Javascript.
Here is a sample of a excel file:
User Name |User ID
Jack Sparrow |U382
Pikachu |U712
Sonic |U555
Mario |U153
Godzilla |U999
James Bond |U007
Ethan Hunt |U053
This is my HTML file:
<!DOCTYPE html>
<html ng-app='myApp'>
<head>
<div>
<div>
<h1>Excel Reader</h1>
</div>
<div id="image">
<img src="432-433.png" width="450" height="300">
</div>
</div>
<script src="angular.js"></script>
<script src="angular-route.js"></script>
<script src="customjs.js"></script>
<script src="xlsx.full.min.js"></script>
<script src="jquery-3.1.1.min.js"></script>
<link rel="stylesheet" href="styles.css">
</head>
<body ng-controller='MyController'>
<div>
<form enctype="multipart/form-data">
<input type="file" id="file">
<button type="submit" value='submit' ng-click="uploadExcel()">Upload File</button>
</form>
</div>
<div>
<table id="myTable">
<thead>
<tr>
<th>User Name</th>
<th>User ID</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</body>
</html>
And this is my Javascript file:
(function () {
var app = angular.module('myApp', []);
app.controller('MyController', ['$scope', myController]);
var excelObj=[];
function myController($scope)
{
$scope.uploadExcel=function()
{
var myFile=document.getElementById ('file');
var input=myFile;
var reader = new FileReader();
reader.onload=function(){
var fileData=reader.result;
var workbook=XLSX.read(fileData,{type: 'binary'});
workbook.SheetNames.forEach(function(sheetName)
{
var rowObject=XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
excelObj=rowObject;
});
for(var i=0;i<excelObj.length;i++)
{
var data=excelObj[i];
$('#myTable tbody:last-child').append("<tr><td>"
+data.User_Name+"</td><td>"
+data.User_ID
+"</td></ tr>");
}
};
reader.readAsBinaryString(input.files[0]);
}
}
})();
I was supposed to let the HTML table display the same data, but all the data ended up undefined. Here is what my table actually displayed:
User Name |User ID
undefined |undefined
undefined |undefined
undefined |undefined
undefined |undefined
undefined |undefined
undefined |undefined
undefined |undefined
What did I miss? How can I fix this issue?
Thanks in advance!

How do I render a data property?

I have this super basic starting point:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" type="text/css" href="Content/dictionary.css" />
<script src="Scripts/kuroshiro.min.js"></script>
</head>
<body>
<div id="searchResultsVue">
<table>
<tr v-for="r in results">
{{ r.Result.ent_seq }}
</tr>
</table>
</div>
<script src="https://vuejs.org/js/vue.js"></script>
<script>
var searchResultsVue = new Vue({
el: '#searchResultsVue',
data: { results: [{ Result: { ent_seq: 'asd' } }] }
});
</script>
</body>
</html>
but I get
[Vue warn]: Property or method "r" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
I don't understand
This is an issue with HTML's lenient rendering practices. When it's building the Dom elements for a table it's expecting a certain structure and anything deviating from that structure is pushed outside the definitions.
And so
<table>
<tr v-for="r in results">
{{ r.Result.ent_seq }}
</tr>
</table>
Acts like
<table>
<tr v-for="r in results">
</tr>
</table>
{{ r.Result.ent_seq }}
The Error is then that it is seeing the call to the loop variable outside the loop.
As seen in this fiddle Adding a table definition tag around your code stops it from being pushed.
You need to fix your markup. tr needs td as its child to work properly.
<tr v-for="r in results">
<td>{{ r.Result.ent_seq }}</td>
</tr>
You have to use the td tag inside tr.
It seems there is something special about table-rows
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div id="searchResultsVue">
<table>
<tr v-for="r in results">
<td>{{ r.Result.ent_seq }}</td>
</tr>
</table>
</div>
<script src="https://vuejs.org/js/vue.js"></script>
<script>
var searchResultsVue = new Vue({
el: '#searchResultsVue',
data: { results: [{ Result: { ent_seq: 'asd' } }] }
});
</script>
</body>
</html>

Angular interating 2 different types of arrays - linear and json array in single ng-repeat

I have a json which has array of string and array of json objects as shown in the code. Have to iterate it using ng-repeat and need to show the string value as it is, if the array is of strings and a specific key's value if the array is of json objects. Please Help!
<html ng-app>
<head>
<script src="https://code.angularjs.org/1.4.9/angular.js">
</script>
</head>
<body>
<div ng-init="data=[
{'name':'Name1','filterValues':['eq1','eq2','eq3','eq4','eq5','eq6']},
{'name':'Name2','filterValues':[{'id':'eid1','description':'Description 1'},{'id':'eid2','description':'Description 2'},{'id':'eid3','description':'Description 3'},{'id':'eid4','description':'Description 4'},{'id':'eid5','description':'Description 5'}]}
]">
<div data-ng-repeat="d1 in data" >{{d1.name}}
<div data-ng-repeat="d2 in d1.filterValues"> {{d2}}</div>
</div>
<span style="color:tomato">"Here, under Name2, I need only the Description Values" </span>
</div>
</body>
</html>
You need to check whether the iterated element has an id property or not. Based on that display d2.description or d2. It can be done with ? conditional operator as below.
{{d2.id?d2.description:d2}}
<html ng-app>
<head>
<script src="https://code.angularjs.org/1.4.9/angular.js">
</script>
</head>
<body>
<div ng-init="data=[
{'name':'Name1','filterValues':['eq1','eq2','eq3','eq4','eq5','eq6']},
{'name':'Name2','filterValues':[{'id':'eid1','description':'Description 1'},{'id':'eid2','description':'Description 2'},{'id':'eid3','description':'Description 3'},{'id':'eid4','description':'Description 4'},{'id':'eid5','description':'Description 5'}]}
]">
<div data-ng-repeat="d1 in data" >{{d1.name}}
<div data-ng-repeat="d2 in d1.filterValues"> {{d2.id?d2.description:d2}}</div>
</div>
<span style="color:tomato">"Here, under Name2, I need only the Description Values" </span>
</div>
</body>
</html>

how to pass a angular-js variable to javascript

so I have this code which displays data from elastic search, the purpose is to get some data, compute a average and display a red or green button.
I'm just starting.
<!doctype html>
<html ng-app="EsConnector">
<link rel="stylesheet" href="styles/main.css">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.js"></script><!-- // a recuperer -->
<script src="scripts/controllers/elasticsearch.angular.js"></script>
<script src="scripts/controllers/es_connect.js"></script>
</head>
<script type="text/javascript">
function addTpsGeocodage(p1) {
alert(p1);
}
</script>
<body>
<title>Dashboard</title>
<h1 align="center">Dashboard </h1>
<hr>
<h3>Services Externes</h3>
<div ng-controller="QueryController">
<div >
<table>
<tr ng-repeat="item in hits">
<td>
{{item['_source']['tpsGecodage']}}
<script>
addTpsGeocodage(item['_source']['tpsGecodage']);
</script>
<span class="green_circle" ng-if="item['_source']['tpsGecodage'] < 1">
Lien
</span>
</td>
</tr>
</table>
</div>
</div>
<br>
Above this line ^^^ should be the results of a test search on the ElasticSearch server.
</body>
</html>
Basically this addTpsGeocodage(item['_source']['tpsGecodage']); (line 29) is doing nothing.
How can I pass a variable from the angular JS scope to the javascript scope.
Thanks
Assign the function to a variable so that it can be accessed globally.
<script type="text/javascript">
var addTpsGeocodage = function(p1) {
alert(p1);
}
</script>
Now, you can access addTpsGeocodage anywhere.

Refresh part of page with JS

I can't update my label with Jquery. It should update after every second on my page but nothing happens. Is there something wrong with my javascript?
Basically what I want to do is update the label every second. But somehow this isn't working. Can anyone please help me out?
Below you can find the code for my 2 files:
////////////// Index.html: /////////////////
<!--AWP_IN_Variable Name='"webdata".AmountOfErrors' -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Gebr. Gerrits Recycling Helmond</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/default.css" rel="stylesheet" type="text/css"/>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="/js/jquery.min.js"></script>
<script src="/js/highcharts.js"></script>
</head>
<body>
<div class="Maindiv">
<div class="header">
<img src="images/gerritslogo800.jpg" class="Logo">
</div>
<div class="content">
<br/>
<table>
<tr>
<th>Part</th>
<th>Value</th>
</tr>
<tr>
<td>Ferro:</td>
<td>0 kg</td>
</tr>
<tr>
<td>Non-Ferro:</td>
<td>0 kg</td>
</tr>
<tr>
<td>Errors:</td>
<td><label id="amountOfErrors" name="amountOfErrors">:="webdata".AmountOfErrors:</label></td>
</tr>
</table>
</div>
<script type="text/javascript">
$(document).ready(function()
{
//query the amountOfErrors variable every second
$.ajaxSetup({ cache: false });
setInterval(function()
{
$.get("IOamountOfErrors.htm", function(result)
{
$('#amountOfErrors').text(result);
});
},1000);
});
</script>
<div class="footer">
Gebr. Gerrits Metaalhandel Helmond B.V. <br/>
Gebr. Gerrits Metaalrecycling B.V. <br/>
Auto Verschrotings Industrie "A.V.I." Den Bosch B.V. <br/>
Euregio Recycling B.V.<br/>
</div>
</div>
</body>
</html>
////////////// IOamountOfErrors.htm: /////////////////
< !-- AWP_IN_Variable Name='"webdata".AmountOfErrors' -->
:="webdata".AmountOfErrors:
(added the space between '<' and '!' else it wouldn't show the code on this site)
Already searched the net for this: I actually found the same stuff that I needed but for me it isn't working: https://www.dmcinfo.com/latest-thinking/blog/id/8567/siemens-s7-1200-web-server-tutorial--from-getting-started-to-html5-user-defined-pages
Please help me out!
Thanks in advance,
Bart
My best would be that you're debugging this local and not on a webserver right?
Because your javascript is trying to do a cross origin requests which doesn't work on file://
EDIT:
Can you try this code
<script type="text/javascript">
$(document).ready(function()
{
//query the amountOfErrors variable every second
setInterval(function()
{
$.post("IOamountOfErrors.htm", function(result)
{
$('#amountOfErrors').text(result);
});
},1000);
});
</script>
Well to update your label you can use setInterval. Here's Code which might be useful
var count = 20;
function myFunction() {
setInterval(function(){ startCounter() }, 1000);
}
$("#counterStart").click(function(e){
myFunction();
});
function startCounter() {
$("#counter").text(count);
}
HTML:
<input type="button" value="counter" id="counterStart" />
<span id="counter">dfsdfs </span>
Working FIDDLE

Categories