mustache - render entire data structure - javascript

Is there some way to render all the literal objects and the literal objects within them using mustache? Being a neophyte at this I wondered if the following would work...
var data2 = {};
data2["collector"]={"sname":"Collector", "lname":"Collector", "V":[11,12,13,14,15]};
data2["storage"] ={"sname":"Storage", "lname":"Storage", "V":[21,22,23,24,25]};
data2["aux1"] ={"sname":"Aux1", "lname":"Loop High", "V":[31,32,33,34,35]};
data2["aux2"] ={"sname":"Aux2", "lname":"Loop Low", "V":[41,42,43,44,45]};
data2["aux3"] ={"sname":"Aux3", "lname":"Aux3", "V":[51,52,53,54,55]};
data2["aux4"] ={"sname":"Aux4", "lname":"Aux4", "V":[61,62,63,64,65]};
var T2 = "<table border='1'>" +
"{{#.}}<tr>" +
"{{#.}}" +
"<td>{{.}}</td>" +
"{{/.}}" +
"</tr>" +
"{{/.}}" +
"</table>"
html = Mustache.to_html(T2, data2);
but of course it doesn't. I get
{{/.}}

Since the goal was to use mustache, here's the final deal using mustache to expand the array.
I don't know if Jesse meant to put embedded literal objects in tables within table or not but that was not my goal. I deleted wrap and all from the function in this version as I either didn't need them or understand why they were there. I remain indebted to Jesse for this hint; I doubt I would have come up with anything so clever.
var getMustache = function(data, depth)
{
var r = "";
if (depth == 0)
{
r=r+"<tr>";
}
for(var d in data)
{
if(data.hasOwnProperty(d))
{
if(typeof data[d] =="object")
{
if (data[d].length) // is it an array?
{
var T = "{{#" + d + "}}<td>{{.}}</td>{{/" + d + "}}";
r += Mustache.to_html(T, data);
}
else
{
r += getMustache(data[d], depth+1);
}
}
else
{
r += "<td>" + data[d] + "</td>";
}
}
if (depth == 0)
{
r=r+"</tr>";
}
}
return r;
}
var T2 = "<table border='1'>" + getMustache(data2,0) + "</table>";
html = Mustache.to_html(T2, data2);
document.write(html);

Seems like you could just make a recursive function for this - mustache is pretty static, but recursion is perfect for looking up all the nodes in a deep object.
Untested hypothetical code:
var data2 = {};
data2["collector"]={"sname":"Collector", "lname":"Collector", "V":[11,12,13,14,15]};
data2["storage"] ={"sname":"Storage", "lname":"Storage", "V":[21,22,23,24,25]};
data2["aux1"] ={"sname":"Aux1", "lname":"Loop High", "V":[31,32,33,34,35]};
data2["aux2"] ={"sname":"Aux2", "lname":"Loop Low", "V":[41,42,43,44,45]};
data2["aux3"] ={"sname":"Aux3", "lname":"Aux3", "V":[51,52,53,54,55]};
data2["aux4"] ={"sname":"Aux4", "lname":"Aux4", "V":[61,62,63,64,65]};
var getMustache = function(data, wrap, all, depth){
var r = "";
var depth = depth || 0;
for(var d in data){
if(data.hasOwnProperty(d)){
r += "<" + wrap[depth] || all + ">";
if(data[d].length){
r += "{{#" + d + "}}";
r += getMustache(data[d], wrap, all, depth ++);
r += "{{/" + d + "}}";
} else {
r += "{{" + data[d] + "}}";
}
r += "</" + wrap[depth] || all + ">";
}
}
return r;
}
var T2 = "<table border='1'>" + getMustache(data2,['tr','td'],'span');
html = Mustache.to_html(T2, data2);

The following works. It doesn't use mustache facilities at all. I plan to change it so that it uses mustache's iteration on the array.
var getMustache = function(data, wrap, all, depth)
{
var r = "";
if (depth == 0)
{
r=r+"<tr>";
}
for(var d in data)
{
if(data.hasOwnProperty(d))
{
if(typeof data[d] =="object")
{
r += getMustache(data[d], wrap, all, depth+1);
}
else
{
r += "<td>" + data[d] + "</td>";
}
}
if (depth == 0)
{
r=r+"</tr>";
}
}
//alert("r=" + r);
return r;
}

Related

Javascript chinese variable being passed to bash script as question mark

I have this javascript function here, the routeno variable will pass a Chinese value
routeno: 粤ZX123港
function getRouteLegNoList()
{
var data = "host="+lphost
+ "&user="+user
+ "&gateway="+gateway
+ "&routedate="+routedate.value
+ "&routeno="+routeno.value
+ "&action=GETROUTELEGNOLIST";
alert(lphost+'|'+user+'|'+gateway+'|'+routedate.value+'|'+routeno.value);
callAjax("../restartAndMoveDeclaration.cgi?"+data, "GET", "",
function(text) {
alert(text);
var html = "<select id=routelegno>";
var count = 0;
var lines = text.split("\n");
for(var i = 0; i < lines.length; i ++)
{
var line = lines[i];
var c;
if(line.indexOf("Data|") == 0) {
count += 1;
c = line.split("|");
html += "<option value=\"" + c[1]
+ "\"";
if(c[1]==origRouteLegNo) {
html += " selected ";
}
html += ">" + c[1] + "</option>";
}
}
html += "</select>";
dvroutelegno.innerHTML = html;
if(count==0){
alert('No Route Legs were found for [' +
gateway + '] [' +
routedate.value + '] [' +
routeno.value + ']');
} else {
if(count==1) {
trroutelegno.style.visibility = 'hidden';
} else {
// More than one, display the select box
trroutelegno.style.visibility = 'visible';
}
}
}
);
}
but when shell script captured the variable it does not read the Chinese character and replaced it as question mark
routeno: ?ZX123?
I've already tried to set different NLS_LANG but encountered the same output
NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
NLS_LANG=AMERICAN_AMERICA.AL32UTF8

Javascript printing html tags as part of innerHTML output to screen

I have a javascript segment that prints output to a div.
output.textContent = "";
for(i=0; i<14; i++){
output.append(document.createElement("p").innerHTML = net_words(sonnet[i]));
output.append(document.createElement("br"));
}
The function net_words that generates the output is as follows:
function net_words(line) {
var net_line = Math.floor(Math.random()*4)
var ret = ""
if (net_line != 1) {
ret += "<span class=\"netno\">"
ret += line
}
else {
var net_list = line.split(" ")
var rand_word = Math.floor(Math.random() * net_list.length)
ret += "<span class=\"netno\">"
for (var i=0; i<net_list.length; i++) {
if (i == rand_word) {
ret += "<span class=\"netyes\">"
ret += net_list[i]
ret += " "
ret += "</span>"
}
else {
ret += net_list[i]
ret += " "
}
}
}
ret += "</span>"
return ret
}
The problem is, it prints the line as follows:
<span class="netno">From fairest creatures we desire increase</span>
That is, it prints it with the HTML tag visible, rather than applied to the code. When I paste it into the text editor for stack overflow, it prints as normal (no tags) unless I put it as a code snippet. What is the cause of this error?
The problem is here:
output.append(document.createElement("p").innerHTML = net_words(sonnet[i]));
You think that you appended <p>, but in fact you appended the result of the assignment. To fix it do:
var p = document.createElement("p");
p.innerHTML = net_words(sonnet[i]);
output.append(p);
or
output.innerHTML += '<p>' + net_words(sonnet[i]) + '</p>';

Facebook Graph API get original picture size not working

Need some help to get a normal or larger image from posts using the Facebook Graph API, at the moment it only gives a 130 x 130 px image in the object.
function fbFetch() {
var access_token = "";
var url = "https://graph.facebook.com/?ids=intel&fields=posts.limit(5){message,created_time,picture.type(normal)}&access_token=' + access_token;
$.getJSON(url, function(response) {
var messages = [];
Object.getOwnPropertyNames(response).forEach(function(page, idx, array) {
response[page].posts.data.forEach(function(post, idx, array) {
messages.push(post);
});
});
function compare(a, b) {
if (a.created_time < b.created_time)
return -1;
if (a.created_time > b.created_time)
return 1;
return 0;
}
var html = "<ul>";
$.each(messages.sort(compare), function(i, fb) {
if (typeof fb.picture != "undefined") {
html += "<li>" + fb.message + "</br>" + '<img SRC="' + fb.picture + '">' + "</br>" + fb.created_time + "</li></br>";
} else {
html += "<li>" + fb.message + "</br>" + fb.created_time + "</li></br>";
}
});
html += "</ul>";
$('.facebookfeed').html(html);
});
}
fbFetch();
<div class="facebookfeed"></div>
Fiddle here: http://jsfiddle.net/6fhq3dat/17/
use full_picture instead of picture
var url = "https://graph.facebook.com/?ids=intel&fields=posts.limit(3){message,created_time,full_picture}&access_token=" + access_token;
demo

How to sort a multidimensional array using items in Javascript [duplicate]

This question already has answers here:
Sort array of objects by string property value
(57 answers)
Closed 7 years ago.
Basically all I want is to sort this array based on each item that is shown below, with the exception of the "Action' and 'Thumb Image' ones. So the way I have it set up is that the header for each of rows is a link, and when that link is clicked the list will be sorted based on what was clicked. So for example, if Title is clicked, then I want to have a "titleSort()" function that will sort based on title. I have no idea how to accomplish this, so any help is much appreciated. I was hoping that VideoList.sort(Title) would work, for example.
Thanks,
JS
for(var i = 0; i<VideoList.length; i++) {
content += "<tr>";
content += "<td width='20%'><a href='https://www.youtube.com/watch?v=" + VideoList[i].VideoID + "'onclick='playVideo("+i+")'>" + "<img src ='https://i.ytimg.com/vi/" + VideoList[i].VideoID + "/hqdefault.jpg' width=175 height=130></a></td>";
content += "<td>" + VideoList[i].Title + "</td>";
content += "<td>" + VideoList[i].VideoID + "</td>";
content += "<td>" + VideoList[i].DateUploaded + "</td>";
content += "<td>" + VideoList[i].Category+ "</td>";
content += "<td>" + VideoList[i].Time+ "</td>";
content += "<td width='20%'>" + VideoList[i].Action + "</td>";
content += "</tr>";
You can use sort to sort VideoList according to title this code may work for you
VideoList.sort(function(a,b){
return a.Title > b.Title;
});
I agree with #manishrw about lodash. AND any number of libraries would make this easier - like jQuery and Angular. There are a ton of table-specific libraries out there that have sort function built in. However, I built it to show how you could do it, including re-building the table once it's sorted. To do that I had to create the array with mock data. Here's a jsfiddle:
https://jsfiddle.net/mckinleymedia/c02nqdbz/
And here's the code:
<div id="target"></div>
<script>
var VideoList = [],
content,
fields = ["Title", "VideoID", "DateUploaded", "Category", "Time", "Action"],
num = 10,
sortField = "Title",
sortDirection = 1,
compare = function(a, b) {
if (a[sortField] < b[sortField]) return -1 * sortDirection;
if (a[sortField] > b[sortField]) return 1 * sortDirection;
return 0;
},
sortArray = function(field) {
if( sortField === field ) sortDirection = -1 * sortDirection;
sortField = field;
VideoList.sort(compare);
buildTable();
},
creatVideos = function() {
for (var x = 0; x < num; x++) {
var video = {},
z = Math.floor(Math.random() * 200);
for (var i in fields) {
if(fields[i]==='VideoID') {
video[fields[i]] = z;
} else {
video[fields[i]] = fields[i] + "-" + z;
}
}
VideoList.push(video);
}
},
buildTable = function() {
content = "<table>";
content += "<tr>";
content += "<th>image</th>";
for (var x in fields) {
content += "<th class='field field-" + fields[x] + "' onclick='sortArray(\"" + fields[x] + "\")'>" + fields[x] + "</th>";
}
content += "</tr>";
for (var i in VideoList) {
content += "<tr>";
content += "<td width='20%'><a href='https://www.youtube.com/watch?v=" + VideoList[i].VideoID + "'onclick='playVideo(" + i + ")'>" + "<img src ='https://i.ytimg.com/vi/" + VideoList[i].VideoID + "/hqdefault.jpg' width=175 height=130></a></td>";
for (var x in fields) {
content += "<td>" + VideoList[i][fields[x]] + "</td>";
}
content += "</tr>";
}
content += "</table>";
document.getElementById('target').innerHTML = content;
};
creatVideos();
buildTable();
</script>
Here's a generic function for you
function sortBy(list, field) {
return list.sort(function(a,b) {
return a[field] < b[field];
});
}
sortBy(VideoList, 'Title');
Warning: sortBy will mutate the list input
You could also make it take a comparator so you control the 'direction' of the sort
// you you need to return -1, 0, or 1 for the sort to work reliably
// thanks, #torazaburo
function compareAsc(a,b) {
if (a < b) return -1;
else if (a > b) return 1;
else return 0;
}
function compareDesc(a,b) {
return compareAsc(a,b) * -1;
}
function sortBy(list, field, comparator) {
return list.sort(function(a,b) {
if (comparator instanceof Function)
return comparator(a[field], b[field]);
else
return compareAsc(a[field], b[field]);
});
}
// default sort ascending
sortBy(VideoList, 'Title');
// sort descending
sortBy(VideoList, 'Title', compareDesc);
Use Lodash library. It's easy to use and efficient in run-time. It has a function sortBy, which can be used to sort a collection based on they key you provide.
P.S. Lodash is my goto Library for any operation to be performed on any collection.

Convert a multidimensional javascript array to JSON?

What is the best way of converting a multi-dimensional javascript array to JSON?
Most of the popular JavaScript frameworks have JSON utility functions included. For instance, jQuery has a function that directly calls a url and loads the JSON result as an object : http://docs.jquery.com/Getjson
However, you can get an open-source JSON parser and stringifier from the json website :
https://github.com/douglascrockford/JSON-js
Then, simply include the code and use the JSON.stringify() method on your array.
The "best" way has been provided by the other posters. If you don't need the full encoding features of the referenced libraries, and only need to encode simple arrays, then try this:
<!DOCTYPE html>
<html>
<head>
<title>Simple functions for encoding Javascript arrays into JSON</title>
<script type="text/javascript">
window.onload = function() {
var a = [
[0, 1, '2', 3],
['0', '1', 2],
[],
['mf', 'cb']
],
b = [
0, '1', '2', 3, 'woohoo!'
];
alert(array2dToJson(a, 'a', '\n'));
alert(array1dToJson(b, 'b'));
};
function array2dToJson(a, p, nl) {
var i, j, s = '{"' + p + '":[';
nl = nl || '';
for (i = 0; i < a.length; ++i) {
s += nl + array1dToJson(a[i]);
if (i < a.length - 1) {
s += ',';
}
}
s += nl + ']}';
return s;
}
function array1dToJson(a, p) {
var i, s = '[';
for (i = 0; i < a.length; ++i) {
if (typeof a[i] == 'string') {
s += '"' + a[i] + '"';
}
else { // assume number type
s += a[i];
}
if (i < a.length - 1) {
s += ',';
}
}
s += ']';
if (p) {
return '{"' + p + '":' + s + '}';
}
return s;
}
</script>
</head>
<body>
</body>
</html>
Not sure I fully understand your question, but if you are trying to convert the object into a string of JSON then you probably want to look at the native JSON support in all the new browsers. Here's Resig's post on it. For browsers that don't yet support it try the json2.js library. JSON.stringify(obj) will convert your object to a string of JSON.
This will convert all combinations of arrays within objects and vice versa including function names:
function isArray(a){var g=a.constructor.toString();
if(g.match(/function Array()/)){return true;}else{return false;}
}
function objtostring(o){var a,k,f,freg=[],txt; if(typeof o!='object'){return false;}
if(isArray(o)){a={'t1':'[','t2':']','isarray':true}
}else {a={'t1':'{','t2':'}','isarray':false}}; txt=a.t1;
for(k in o){
if(!a.isarray)txt+="'"+k+"':";
if(typeof o[k]=='string'){txt+="'"+o[k]+"',";
}else if(typeof o[k]=='number'||typeof o[k]=='boolean'){txt+=o[k]+",";
}else if(typeof o[k]=='function'){f=o[k].toString();freg=f.match(/^function\s+(\w+)\s*\(/);
if(freg){txt+=freg[1]+",";}else{txt+=f+",";};
}else if(typeof o[k]=='object'){txt+=objtostring(o[k])+",";
}
}return txt.substr(0,txt.length-1)+a.t2;
}
You could use the encode function of this library.
I've modified a bit the code previously provided... because a JSON has this format: [{"object":{"property_1":"value_1","property_2":"value_2"}}]
So, the code would be...
<!DOCTYPE html>
<html>
<head>
<title>Simple functions for encoding Javascript arrays into JSON</title>
<script type="text/javascript">
window.onload = function(){
var a = [['property_1','value_1'],['property_2', 'value_2']];
alert("Comienzo..., paso ////"+a+"\\\\\\ a formato JSON");
var jsonSerialized = array2dToJson(a, 'object');
alert(jsonSerialized);
};
// Estructura de JSON [{"object":{"property_1":"value_1","property_2":"value_2"}}]
function array2dToJson(a, p, nl) {
var i, j, s = '[{"' + p + '":{';
nl = nl || '';
for (i = 0; i < a.length; ++i) {
s += nl + array1dToJson(a[i]);
if (i < a.length - 1) {
s += ',';
}
}
s += nl + '}}]';
return s;
}
function array1dToJson(a, p) {
var i, s = '';
for (i = 0; i < a.length; ++i) {
if (typeof a[i] == 'string') {
s += '"' + a[i] + '"';
}
else { // assume number type
s += a[i];
}
if (i < a.length - 1) {
s += ':';
}
}
s += '';
if (p) {
return '{"' + p + '":' + s + '}';
}
return s;
}
</script>
</head>
<body>
<h1>Convertir un Array a JSON...</h1>
</body>
</html>
var t = {}
for(var i=0;i<3;i++) {
var _main = {};
var _dis = {}
var _check = {};
_main["title"] = 'test';
_main["category"] = 'testing';
_dis[0] = '';
_dis[1] = '';
_dis[2] = '';
_dis[3] = '';
_check[0] = 'checked';
_check[1] = 'checked';
_check[2] = 'checked';
_check[3] = 'checked';
_main['values'] = _check;
_main['disabled'] = _dis;
t[i] = _main;
}
alert(JSON.stringify(t));
Try this
use this code and very simple develop for more two array
function getJSON(arrayID,arrayText) {
var JSON = "[";
//should arrayID length equal arrayText lenght and both against null
if (arrayID != null && arrayText != null && arrayID.length == arrayText.length) {
for (var i = 0; i < arrayID.length; i++) {
JSON += "{";
JSON += "text:'" + arrayText[i] + "',";
JSON += "id:'" + arrayID[i] + "'";
JSON += "},";
}
}
JSON += "]"
JSON = Function("return " + JSON + " ;");
return JSON();
}
and 3 array
function getJSON(arrayID, arrayText, arrayNumber) {
var JSON = "[";
if (arrayID != null && arrayText != null && arrayNumber!=null && Math.min(arrayNumber.length,arrayID.length)==arrayText.length) {
for (var i = 0; i < arrayID.length; i++) {
JSON += "{";
JSON += "text:'" + arrayText[i] + "',";
JSON += "id:'" + arrayID[i] + "',";
JSON += "number:'" + arrayNumber[i] + "'";
JSON += "},";
}
}
JSON += "]"
JSON = Function("return " + JSON + " ;");
return JSON();
}
JavaScript will correctly encode an object:
var a = new Object;
var a = {};
JavaScript will not encode an array:
var a = new Array();
var a = [];

Categories