Mustache.js iterate over all arrays - json

I'm still busy trying to setup a JSON file to a HTML website. So if the json changes the changes are dynamically loaded in the HTML. Till this far i'm able to retreive the content and even request some content. But not everything that i want because the markup from the JSON is a bit weird.
Because of the cross-site protection I was not able to do a JSOP request directly, so i solved that with a little trick i saw somewhere. I've created a test.php that simply does:
That way I circumvent the cross-site protection, and everything works well. Only problem is that I can't iterate over all the arrays that i want. Currently i'm using the following script to do a JSOP call and get the data. And the output is a nice description between the <li></li>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
</head>
<body>
<ul id="episodes">
</ul>
<script src="http://cdnjs.cloudflare.com/ajax/libs/mustache.js/0.7.0/mustache.min.js"></script>
<script src="http://ps3scenefiles.com/json/handlebars.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script id="episodes-template" type="text/template">
<li>{{description}}</li>
</script>
<script>
$(function() {
$.getJSON('http://ps3scenefiles.com/json/test.php', function(data) {
var template = $('#episodes-template').html();
var info = Mustache.to_html(template, data);
$('#episodes').html(info);
});
});
</script>
</body>
</html>
But when you open the link to the JSON (http://ps3scenefiles.com/json/test.php), you see that the Episodes array has another array with just numbers. How can i create a list like
Episode: 1
Id:13605 Active:true Lang:en Link: url
Id:16525 Active:true Lang:ru Link: url
Episode: 2
Id:14854 Active:true Lang:en Link: url
Id:19445 Active:true Lang:ru Link: url
So to be clear, how can i do a mustache (or handlebars) templating to make it look like the example?

You can use Handlebars helper as mentioned in this answer
Here is a fiddle without styling, that prints out the data you expect (sort of, not all fields).
Here is the helper function -
Handlebars.registerHelper('eachkeys', function(context, options) {
var fn = options.fn, inverse = options.inverse;
var ret = "";
var empty = true;
for (key in context) { empty = false; break; }
if (!empty) {
for (key in context) {
ret = ret + fn({ 'key': key, 'value': context[key]});
}
} else {
ret = inverse(this);
}
return ret;
});

Related

Parsing Html Page with Dart

I m trying to parse the following entry in an HTTP get request.
In the body, you see a script tag with a function call where I need to have access to the JSON inside the HTML tag.
<!DOCTYPE html>
<html translate="no">
<head></head>
<body>
<script>
$(function() {
intranet.list.frontend.init({
gridDataAndConfiguration: {
"Here is a big Json - WANTED"
},
},
});
</script>
</body>
</html>
Up to now, I don't parse the HTML with any Dart specific parsing method like
"parse" from package:html/parser.dart. That attempt was successful in searching for all the "script" tags inside the HTML DOM, but unfortunately, I did not find or showed the JSON or function call inside the referred script Tag!
The question is, how to access the JSON in the given HTML Page using Dart?
Solution :
RegExp re = RegExp(r'\[\{.*?\}\]');
var parsedHtml = parse(htmlText);
var allScripts = parsedHtml.getElementsByTagName('script');
for (int i = 0; i < allScripts.length; i++) {
if (allScripts[i].innerHtml.contains(startString)) {
Iterable<String> result =
re.allMatches(allScripts[i].innerHtml).map((m) => m[0]);
List<dynamic> jsonParsed = [];
for (var match in result) jsonParsed.add(jsonDecode(match));
Thanks for your answer & help.

Parse multi level JSON from URL

All.
I found this script which is rather promising for what I am trying to do.
It works great with the hardcoded XML script.
However, I need to parse the file itself from an external URL.
Thank You.
Contents of the example file.
{"icestats":{"admin":"admin","host":"192.168.2.203","location":"Radio","server_id":"Icecast 2.4.4","server_start":"Mon, 24 May 2021 16:54:10 +0000","server_start_iso8601":"2021-05-24T16:54:10+0000","source":{"audio_info":"channels=2;samplerate=44100;bitrate=256","channels":2,"genre":"various","listener_peak":3,"listeners":2,"listenurl":"http://192.168.2.203:8000/RadioOne","samplerate":44100,"server_description":"Unspecified description","server_name":"RadioOne","server_type":"audio/mpeg","stream_start":"Mon, 24 May 2021 21:59:34 +0000","stream_start_iso8601":"2021-05-24T21:59:34+0000","title":"KISS - Hide Your Heart","dummy":null}}}
Example of the linked file. (This is an example of the URL file, in the real-world URL, it will be my domain name, with the file attached to it. This file cannot be removed from the location it is at, it is sitting on another server in the network.)
http://192.168.2.203:8000/status-json.xsl
Full script (This will run and show the hardcoded XML tree without any modifications to the file)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Parse Nested JSON Data in JavaScript</title>
</head>
<body>
<script>
/* Storing multi-line JSON string in a JS variable
using the new ES6 template literals */
var json = '{"icestats":{"admin":"admin","host":"192.168.2.203","location":"Radio","server_id":"Icecast 2.4.4","server_start":"Mon, 24 May 2021 16:54:10 +0000","server_start_iso8601":"2021-05-24T16:54:10+0000","source":{"audio_info":"channels=2;samplerate=44100;bitrate=256","channels":2,"genre":"various","listener_peak":3,"listeners":2,"listenurl":"http://192.168.2.203:8000/RadioOne","samplerate":44100,"server_description":"Unspecified description","server_name":"RadioOne","server_type":"audio/mpeg","stream_start":"Mon, 24 May 2021 21:59:34 +0000","stream_start_iso8601":"2021-05-24T21:59:34+0000","title":"KISS - Hide Your Heart","dummy":null}}}';
// This is the link to the file; the file contents are what is above.
//var json = "http://192.168.2.203:8000/status-json.xsl";
// Converting JSON object to JS object
var obj = JSON.parse(json);
// Define recursive function to print nested values
function printValues(obj) {
for(var k in obj) {
if(obj[k] instanceof Object) {
printValues(obj[k]);
} else {
document.write(obj[k] + "<br>");
};
}
};
printValues(obj);
document.write("<hr>");
document.write(obj["icestats"]["source"]["title"]);
</script>
</body>
</html>
When I run the script with the URL link only, I get the following error.
Uncaught SyntaxError: Unexpected token h in JSON at position 0
at JSON.parse (<anonymous>)
at music2.asp:18
Which points to this line.
var obj = JSON.parse(json);
This code was provided for me and it works great.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Zvonko *</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<script>
// fetch the JSON data from your URL:
jQuery.get( "http://localhost:8000/status-json.xsl" , showData, "json" );
function showData(data){
// no need to Converting JSON string to JS object
// jQuery converted it for you
//var obj = JSON.parse(data);
printValues(data);
document.write("_______________________________");
if(data["icestats"] && data["icestats"]["source"]){
document.write(data["icestats"]["source"]["title"]);
// This next line, I use to pass a variable to an input field to submit to the database.
$(".myid").val(data["icestats"]["source"]["title"]);
}
// Converting your JSON string from top to JS object
var jsonobj = JSON.parse(yourJson);
printValues(jsonobj);
document.write("_______________________________");
if(jsonobj["icestats"] && data["icestats"]["source"]){
document.write(jsonobj["icestats"]["source"]["title"]);
}
}
// Define recursive function to print nested values
function printValues(obj) {
for(var k in obj) {
if(obj[k] instanceof Object) {
printValues(obj[k]);
} else {
document.write(k + ": " + obj[k]);
};
}
};
</script>
</body>
</html>
<form action="Send.asp" method="post">
<input type="text" name="Title" class="myid" style="border:1px double #000;">
<input type="submit" name="Submit">
</form>
Thanks to, Zvonko, for the code, on another side.
This one is completed.

How to only send HTTP response as plain text (HTML) [duplicate]

This question already has answers here:
What is the difference between client-side and server-side programming?
(3 answers)
Closed 2 years ago.
I need to implement a calculator on my webpage, which will receive some arguments in the url and is supposed to return just the result, nothing else.
Example:
http://example.com/calc/?x=244&y=123&op=plus
I wrote a program using HTML and JavaScript which returns the correct result and prints it on the webpage.
This prints the result.
But the client doesn't just receive the result, but the whole html & script. Does anyone know how I can send only the result to the client?
Edit: If this cannot be done with HTMP and JS, how else?
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
function calculate(url) {
// ...
}
let url = window.location.href;
document.write(parseInt(calculate(url)));
</script>
</body>
</html>
Desired result: 367 is returned to the HTTP client
Actual result: < !DOCTYPE html> .... ...... is returned to the HTTP client
Try the following
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
function calculate (url_string) {
try {
var url = new URL(url_string);
var x = parseInt(url.searchParams.get("x"));
var y = parseInt(url.searchParams.get("y"));
switch(url.searchParams.get("op")){
case "plus": return x + y;
// add more cases here
}
} catch(e){}
}
let url = window.location.href;
document.write(parseInt(calculate(url)));
</script>
</body>
</html>

Pagination with JQuery on HTML Page

I'm using Go to write the backend with MongoDB. I am using JQuery AJAX to send requests to the API.
I have an API that accepts parameters (page, limit, offset) and returns all records as a response. I want to perform pagination and send these parameters on page Number button click. I have approx 4,50,000 records in the collection.
I have searched some examples using pagination plugin but from what I understood it will first load all records from DB then perform pagination but I do not want to load all records because I am already sending (page, limit, offset parameters to limit records. How we can do that using HTML and JQuery?
<a href='#' onclick='getRecords(page,limit,offset)'>1</a>
I am using using Find().skip().limit().All(&result) in golang. And My HTML code is like first table show first 10 rows from db and then
<a herf='' onclick='getRecords(1,10,0)'>1</a>
<a herf='' onclick='getRecords(2,10,10)'>2</a>
<a herf='' onclick='getRecords(3,10,20)'>3</a>
...
function getRecords(page,limit,offset)
{
$.ajax(){}
}
I want to do it dynamic with next and prev like pagination
This is the most straightforward example I could come up with.
Initially you would populate the results server side with an html template. Or you could have a script do it and populate them similar to how I am doing it in the button click callback.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JQuery Pagination</title>
</head>
<body>
<ul>
<li>1</li>
<li>1</li>
<li>1</li>
</ul>
prev
<span>
</span>
next
</body>
<script
src="https://code.jquery.com/jquery-3.5.1.js"
integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc="
crossorigin="anonymous"></script>
<script>
let currentPage = 1
let $searchList = $("body > ul")
let $prevButton = $("#prev")
let $nextButton = $("#next")
let maxPages = 23
let maxPageButtons = 5
let pageButtonClick = function() {
currentPage = parseInt($(this).text())
update(currentPage)
console.log(currentPage)
}
let update = function(currentPage) {
$searchList.children().each(function() {
$(this).text(currentPage)
})
let basePage = currentPage
if (basePage + maxPageButtons > maxPages) {
basePage = maxPages - maxPageButtons + 1
}
let basePageOffset = 0
let $newPageButtons = $()
while (basePageOffset < maxPageButtons) {
$newPageButtons = $newPageButtons.add(`${basePage + basePageOffset}`)
basePageOffset++
}
$("span").children().remove()
$("span").append($newPageButtons)
$("span > a").on("click", pageButtonClick)
// Get results and display them.
}
update(currentPage)
$prevButton.on("click", function() {
if (currentPage > 1) {
currentPage--
update(currentPage)
}
})
$nextButton.on("click", function () {
if (currentPage < maxPages) {
currentPage++
update(currentPage)
}
})
</script>
</html>
JSFiddle
If you want to put html in the list item then use the html() method.
It looks like the pagination plug-ins you are using are frontend facing. I would suggest to rewrite the querying of data in your backend in a way such that only the required data is sent to the frontend instead of all the records. You can use the limit(), for limit, and skip(), for offset, mongodb methods interfaces that your driver offers.
Check out this answer to understand how to do this for mongo-go-driver. If you are using any other driver, you can use an equivalent of what's being used in the mongo-go-driver.

How to create resuable showModalDialog() in Google App Script?

I have ModalDialog that prompts for user date range selection in order to generate the appropriate info. I have several menu items that uses the same prompt so I want to reuse the ModalDialog.
// Available method
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Options for Menu Item N');
// What I hope is available
SpreadsheetApp.getUI().showModalDialog(htmlOutput, 'Options for Menu Item N', userdataN); // pseudocode
// inside HTML
var userdata = Script.host.environment // pseudocode do something with userdata in HTML
However, the showModalDialog() function does not allow me to pass any user data to the html so I have no way to identify which menu item I need to return the user selection to.
How can I create a reusable ModelDialog in this case?
EDIT:
I realized I can write the environment variable value in a sheet and then later from the HTML retrieve the value, but is there a cleaner way to do it?
You could either pass the user data object as a property of the HtmlTemplate object and use scriptlet syntax (see this answer) or do string interpolation. Personally, I prefer the latter option over using Google's built-in template engine. It's slower but much more flexible.
Suppose we have an HTML page called 'app' in the script editor
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h1>{{global.app}}</h1>
<div id=container>
<ul>
<li>{{name}}</li>
<li>{{email}}</li>
<li>{{age}}</li>
</ul>
Created by {{global.author}}.
</div>
</body>
</html>
You can call HtmlService methods to serve the template as a string.
//serve HTML template as a string
function getTemplateAsString(filename) {
return HtmlService.createTemplateFromFile(filename).getRawContent();
}
You can then pass the html string to the interpolation function:
var config = {
app: "My app",
author: "me"
};
function interpolateString(htmlString, params) {
//Add global variables to the template
for (var configKey in config) {
if (config.hasOwnProperty(configKey)) {
htmlString = htmlString.replace("{{global." + configKey + "}}", config[configKey]);
}
}
//Insert page-specific parameters
for (var paramsKey in params) {
if (params.hasOwnProperty(paramsKey)) {
htmlString = htmlString.replace("{{" + paramsKey + "}}", params[paramsKey]);
}
}
return htmlString;
}
For the last step, you create the HtmlTemplate object from the resulting string and call the 'evaluate()' method on it. Calling evaluate returns a valid HtmlOutput object instance that you can pass to UI methods
var template = HtmlService.createTemplate(htmlString);
ui.showModalDialog(template.evaluate(), "My dialog");