I'm looking for a very basic example of using Javascript to parse a JSON file and output an html file or populate an html file. All the examples I've located so far have code snippets and I don't have the background to fill in the blanks between.
Thank you for any fiddles (which would be awesome), links, and smart a*s comments.
Templating example
I would suggest on of templating tools for example PURE...
The purpose of such a tool is separation of logic and representation.
For example, generating a list from JSON data using mentioned tool would look like this:
JSON data file
{'who':'BeeBole!'}
HTML file
<html>
<head>
<title>PURE Unobtrusive Rendering Engine</title>
<script src="../libs/jquery.js"></script>
<script src="../libs/pure.js"></script>
</head>
<body>
<!-- the HTML template -->
Hello <a class="who" href="#"></a>
<script>
// the JSON data we want to render
$.getJSON('yourJSONdataFile.json', function(data) {
// run the rendering
$('a').autoRender(data);
// PURE tries to match class with the JSON property and replace the node value with the value of the JSON property
});
</script>
</body>
</html>
This is most basic approach appropriate if you have simple JSON data (see working JSFiddle example there).. Get Started guide will walk you trough another example if basic approach isn't suitable. For more advanced features take look at the documentation.
Alternatives
There was no particular reason that PURE has been used in above example. There are many other alternatives out there:
EJS
Mustache
Tempo
...
...or you can do it manually as explained there.
You can use a microtemplating library, like Mustache, to parse incoming JSON objects into HTML snippets using {{ key }} template syntax. If your object looks like:
var myObj = {
name: 'Joe Smith',
age: 25,
features: {
hairColor: 'red',
eyeColor: 'blue'
}
};
Using Mustache, you can render it into HTML easily using {{#}} and {{/}} to traverse nested objects:
Mustache.render('Hello, my name is {{name}} and I am {{age}} years old. {{#features}} I have {{hairColor}} hair and {{eyeColor}} eyes.{{/features}}', myObj);
which outputs:
Hello, my name is Joe Smith and I am 25 years old. I have red hair and blue eyes.
EDIT: more germane application - dynamically generate a control panel using a template with nested lists of objects. Here's my template and object (HTML broken into a list and joined for clarity):
var panel = [
'<div id="cpanel">',
'{{#cpanel}}',
'<div class="panel_section">',
'<h1 class="cpanel">{{name}}</h1>',
'<p>',
'{{#content}}',
'<button id="{{id}}">{{id}}</button>',
'{{/content}}',
'</p>',
'</div>',
'{{/cpanel}}',
'</div>',
].join('\n');
var panelObj = {
cpanel: [
{
name: 'playback',
content: [
{id: 'play'},
{id: 'pause'},
{id: 'stop'}
]
}, {
name: 'zoom',
content: [
{id: 'zoomIn'},
{id: 'zoomOut'}
]
}]
};
Then you render with Mustache:
Mustache.render(panel, panelObj);
which outputs:
<div id="cpanel">
<div class="panel_section">
<h1 class="cpanel">playback</h1>
<p>
<button id="play">play</button>
<button id="pause">pause</button>
<button id="stop">stop</button>
</p>
</div>
<div class="panel_section">
<h1 class="cpanel">zoom</h1>
<p>
<button id="zoomIn">zoomIn</button>
<button id="zoomOut">zoomOut</button>
</p>
</div>
</div>
You might want to look at jQuery.dForm. It helps creating HTML and forms dynamically using JSON.
So i am assuming you mean your JSON contains the HTML string inside it.
lets say your JSON is:
{
"htmlString" : "<div> now thats smart! </div>"
}
you can render this in your HTML by writing your HTML as follows:
<html>
<head>
var myjson = {"htmlString" : "<div> now thats smart! </div>"}
<script type="text/javascript">
function loadHTML() {
document.getElementByTagName("body").innerHTML(myjson["htmlString"]);
}
</script>
</head>
<body onload='loadHTML()'>
</body>
</html>
Note that you can also use AJAX to fetch your JSON and render it
however, note that embedding HTML inside JSON when transporting from server is considered a security vulnerability.
Instead, you can fetch a partial HTML from the server directly by using AJAX and then replace portions of that HTML (template) with dynamic values by using javascrip and REST/SOA
hope this helps
EJS or embedded java script which is nice and fun. You could use a front end framework like backbone or facebook's React which is allot more complex. There are some good video tutorials on codeschool's node lesson for EJS. here is an example
var foo = {'city':'SF', 'party':'now'}
with EJS its as simple as:
<div> <p> going to <%= foo.city %> to party <%= foo.party %> </p></div>
to get text:' going to SF to party now'
With EJS, or my fav PEJS you can do if, switch, for(), Date() ..... you get the point. look Here for Pejs and also read EJS. Lots of cool stuff you can do
Related
That title might be a little confusing but I don't know how to put it otherwise. I have some JSON encoded data in a .json-file:
{"foo":"bar", "bar":"foo", "far":"boo"}
and some HTML content in a .html-file:
<h1>I'm a Title</h1>
<p>Lorem Ipsum</p>
<br>
<img src="./media/foo.png">
There is a jQuery script that takes the data from both files ($.getJSON() and $(#div).load()) and creates a page with some predefined head, uses the html as content and the json data to create some buttons (key=destination & value=name) on there.
Because the project has many of these pages I would love to have only one file that holds both my HTML content AND the JSON data so I had all I needed for one page would be a single file access. So the question really is: How can I store both JSON and HTML data in one file so jQuery can access, distinguish and process it?
This is part of an electron application but I'm not sure if that even matters for that question.
The content of the json file assuming it is a json object can be assigned to a javascript variable in the html document in a script tag.
Then to refer to, for example foo, you use theJsonObject.foo;
With the following javascript snipet you can see inthe browser's console the name of each property an the value.
How you mix this in your current code depends on how you are writting it. But make sure the variable is declared before you use it.
for (let prop in theJsonObject) {
console.log( prop + ": " + theJsonObject[prop] );
};
<html>
<head>
....
<script>
var theJsonObject = {"foo":"bar", "bar":"foo", "far":"boo"};
</script>
</head>
<body>
....
</body>
</html>
I'm trying to achieve something similar to what JSRender does, but I'm not sure how to go about it. Consider the HTML "template" below:
<!DOCTYPE html>
<body>
<div class="content">
<div class="notifications">{{:notifications}} notifications</div>
<div class="something else">this is {{:something_else}} to show</div>
</div>
</body>
</html>
Supposed I have JSON data like so:
{"notifications": "3", "something_else": "some arbitrary data"}
How do I populated this data into the HTML page? The way JSRender does it seems to involve creating a separate template in a <script> tag, then populating the data into the template and finally copying the template into an empty container. Is there a way to avoid this template redefinition? I believe my HTML page can already act like a template as demonstrated above.
The Question: is it possible to display JSON data into a ready HTML page (such as above) with defined "data positions"? As part of the challenge, using $('.notifications').html()-related methods should be avoided since this would be cumbersome when handling large extensive data.
You can do that using top-level JsViews top-level data-linking - with an element such as a <span> for each insertion point.
<div class="content">
<div >this is <span data-link="something_else></span> to show</div>
...
Code:
$.link(true, ".content", data);
In addition, the data is data-bound to the HTML.
Here is a sample which shows the data-binding by letting you actually change a data property dynamically:
It also shows data-linking to the src and title attributes of an <img> tag. See here for more information about different data-link targets.
var data = {notifications: "3", something_else: "some arbitrary data",
imgData: {img1: {src: "http://www.jsviews.com//icons/android-chrome-36x36.png",
desc: "some image"}}};
$.link(true, ".content", data, {replace: true});
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsviews/0.9.90/jsviews.js"></script>
<div class="content">
<div ><span data-link="notifications"></span> notifications</div>
<div >this is <span data-link="something_else"></span> to show</div>
<img data-link="src{:imgData.img1.src} title{:imgData.img1.desc}"/>
<br/>Edit: <input data-link="something_else"/>
</div>
While BorisMoore's answer addresses the question adequately, I crafted a "hack" that also appears to work with the ability to support attributes on almost all elements, though I don't know to what extent it is reliable.
However, this requires one to change the data structure to also indicate the type of element and even the part of it (attribute) where the data is to be inserted. The data would need to look like so:
{"notifications": "span:|3", "something_else": "span:|some arbitrary data", "avatar":"img.alt:|A"}
Then in JQuery, one could do something like so:
$.each(data, function(key, value) {
value = value.split(":|");
var element = value[0];
value = value[1];
if(element.indexOf('.') == -1){
var content = $(element + ':contains("{{:'+key+'}}")').last().html().replace("{{:"+key+"}}", value);
$(element + ':contains("{{:'+key+'}}")').html(content);
}else{
element = element.split('.');
var attribute = element[1];
element = element[0];
$(element + '['+attribute+'="{{:'+key+'}}"]').last().attr(attribute, value);
}
});
EDIT: The main drawback of this method is that it unbinds all attached events when an elements property is modifed this way.
I have some HTML templates inside of jQuery code, I use them for generating some new elements with JS. Currently, I keep them in the bottom of my page as
<script type="text/html" id="ID_to_refer_from_jQuery">...HTML code here...</script>
I feel it's not the best way to do this, because some of them are pretty big, is there a way to store string HTML templates outside of HTML file?
Put them in another folder and call them in with AJAX. You don't want to have one huge file. Rather, leverage the organizational folder system to keep your project organized.
Example Folder Structure
/root
index.html
/templates
navigation.html
footer.html
...
Loading Them In
$("header").load("templates/navigation.html");
The best way to do this is to use the HTML5 template feature, but unfortunately it is not supported by Internet Explorer 10 or 11. Here is an example of it in use though:
<template id="simple">
<style>
span { color: purple; }
</style>
<img src="http://placehold.it/50x50" />
<span>Hello World!</span>
<script>
function boom(){
alert("BOOM!");
}
boom();
</script>
</template>
function addSimple(){
// Grab our template
var t = document.querySelector('template#simple').content;
// Optional -- Modify template
// Clone and add
var clone = document.importNode(t, true);
document.getElementById("simple-target").appendChild(clone);
}
(Source of this example)
In the mean time the most common way I've seen is to put your HTML in a JavaScript variable like this:
var html = [
'<div>',
' <h1>Example Domain</h1>',
' <p>This domain is established to be used for illustrative examples in documents. You may use this',
' domain in examples without prior coordination or asking for permission.</p>',
' <p>More information...</p>',
'</div>'
].join('');
If you have a chunk of HTML, there is even an online tool that will format it as a JavaScript variable automatically.
I am in beginning of a web project and I want to read my web site stings such as labels, title of pages, placeholder and ... from a json file. i think this approach may help me to increase my speed in changes and create a multi language web site.
is there any jquery library for doing this? and if ther is not how can i do this work by jquery?
You can make mustache templates and populate them with data using handlebars.js:
http://handlebarsjs.com/
Mustache templates use curly braces as placeholders and handlebars uses the json format to hold the data. It could look something like this (though not a full working example):
HTML:
<div class="entry">
<h1>{{title}}</h1>
<div class="body">
{{body}}
</div>
</div>
Javascript:
var context = {title: "My New Post", body: "This is my first post!"};
var html = template(context);
Result:
<div class="entry">
<h1>My New Post</h1>
<div class="body">
This is my first post!
</div>
</div>
Here is a working example: https://jsfiddle.net/k4u64exL/
What you're searching for is a Javascript/jQuery Template Engine - there are lot of them (start e.g. with http://www.sitepoint.com/10-javascript-jquery-templates-engines/ ).
If you want to write your own template engine try the following:
1) Fetch JSON-Data with Ajax
2) Fetch Template with Ajax
3) Apply variables from JSON-File to Template File (simple replace)
4) Append the result to the current page.
I would like to display a list of hotels in HTML using data from this Google sheet:
https://docs.google.com/spreadsheets/d/1pksFEATRRWfOU27kylZ1WLBJIC-pMVxKk9YlCcDG0Kk/
I am using JSON and jQuery, and would like to use jQuery to loop over all of the rows, displaying them in HTML format.
So far I have managed to display some content using JSON but I am unsure how to proceed with displaying all of the rows:
Codepen: http://codepen.io/aljohnstone/pen/adobow
$.getJSON('http://cors.io/?u=https://spreadsheets.google.com/feeds/list/1pksFEATRRWfOU27kylZ1WLBJIC-pMVxKk9YlCcDG0Kk/od6/public/values?alt=json',function(data){
//remove http:// for a text
var url = data.feed.entry[0]['gsx$url']['$t'];
var shortUrl = url.replace('http://', '');
//give id's google sheet values
$('#bandb').text(data.feed.entry[0]['gsx$name']['$t'])
$('#description').text(data.feed.entry[0]['gsx$description']['$t'])
$('#image').attr("src", (data.feed.entry[0]['gsx$image']['$t']));
$('#link').text(shortUrl).attr("href", (data.feed.entry[0]['gsx$url']['$t']));
});
Use jquery foreach
$.getJSON('http://cors.io/?u=https://spreadsheets.google.com/feeds/list/1pksFEATRRWfOU27kylZ1WLBJIC-pMVxKk9YlCcDG0Kk/od6/public/values?alt=json',function(data){
$.each(data.feed.entry,function(i,v){
var url = v.gsx$url.$t;
var shortUrl = url.replace('http://', '');
var data = $('<div class="listing">').append('<img src="'+v.gsx$image.$t+'" id="image"/><h4 id="bandb">'+v.gsx$name.$t+'</h4><p id="description">'+v.gsx$description.$t+'</p>'+shortUrl+'');
$('body').append(data);
});
});
http://codepen.io/anon/pen/mVbypE?editors=001
I'd recommend using a front-end templating framework, such as mustache.js. There are a lot of options in this area. What you will typically do in a templating framework is define an HTML template that uses placeholders for your data. Then, in your javascript, you'll pass the data object into the templates. Here's how it might look in mustache:
Template
<script id="listing-template" type="text/html">
<div class="listing">
<img class="image" src="{{gsx$image.$t}}"/>
<h4 class="bandb">{{gsx$name.$t}}</h4>
<a class="link" href="{{gsx$url.$t}}">{{gsx$url.$t}}</a>
<p class="description">{{gsx$description.$t}}</p>
</div>
</script>
JavaScript
<script>
$.getJSON('http://cors.io/?u=https://spreadsheets.google.com/feeds/list/1pksFEATRRWfOU27kylZ1WLBJIC-pMVxKk9YlCcDG0Kk/od6/public/values?alt=json',function(data){
// loop through the entry object and append new templated elements to body element
$("body").mustache("listing-template",data.feed.entry);
});
</script>
I left out the initialization details for the mustache framework, but this is the general idea.