How to create HTML via Javascript from JSON input? - javascript

This is reality
This is the expectation
What I'm trying to do here:
I have JSON data of 60 elements with nested data inside. I am currently able to successfully display them via hard coding. This is easy because I only display 5 results now. But, I need to display all 60. This, obviously, is highly inefficient to hard-code, not to mention bad practice.
But injecting HTML via JS has got me stumped.
for (var c = 0; c < 20; c++) {
html += '<div>';
html += '<div class="card text-center">';
html += '<div class="card-header">';
html += '<h5><strong id="name'+c;'"></strong> - <span id="sv'+c;'"></span>';
html += '</div>';
html += '<div class="card-body text-left">';
html += '<ul style="list-style-type:none;">';
html += '<li><strong>Flights:</strong> <span id="flights'+c;'"></span></li>';
html += '<li><strong>Contributed:</strong> <span id="cont'+c;'"></span></li>';
html += '<li><strong>Cont/Flight:</strong> <span id="cpf'+c;'"></span></li>';
html += '<li><strong>Avg Cont/Day:</strong> <span id="avgcd'+c;'"></span></li>';
html += '<li><strong>Joined:</strong> <span id="join'+c;'"></span></li>';
html += '</ul>';
html += '</div>';
html += '</div>';
}
console.log(html);
//console.log(allCont, allJoined, allFlights);
document.getElementById("content").innerHTML = html;
This is the code I've written to attempt this, but it outputs something very undesirable as in seen in the "reality" photo. This is the code, in normal HTML, I'm trying to inject:
<div id="content">
<div class="card text-center">
<div class="card-header">
<h5><strong id="name0"></strong> - <span id="sv0"></span></h5>
</div>
<div class="card-body text-left">
<ul style="list-style-type:none;">
<li><strong>Flights:</strong> <span id="flights0"></span></li>
<li><strong>Contributed:</strong> <span id="cont0"></span></li>
<li><strong>Cont/Flight:</strong> <span id="cpf0"></span></li>
<li><strong>Avg Cont/Day:</strong> <span id="avgcd0"></span></li>
<li><strong>Joined:</strong> <span id="join0"></span></li>
</ul>
</div>
</div>
</div>
The loop ending at 20 is just a sample run. What I need it to do is of course loop through the length of the JSON file, which is of course just a matter of replacing "20" with "data.length".
The IDs need to graduate as well, e.g., name0, name1, name2 for each bootstrap card I'm trying to output here.
What stumps me here, though, is that the console.log(html) outputs an HTML structure that looks good to me:
<div><div class="card text-center"><div class="card-header"><h5><strong id="name19</div><div class="card-body text-left"><ul style="list-style-type:none;"><li><strong>Flights:</strong> <span id="flights19<li><strong>Contributed:</strong> <span id="cont19<li><strong>Cont/Flight:</strong> <span id="cpf19<li><strong>Avg Cont/Day:</strong> <span id="avgcd19<li><strong>Joined:</strong> <span id="join19</ul></div></div>
I hope I have explained the problem, do ask for more details as required. Thanks!

Related

HTML DOM have data I didn't add through Javascript

I have generated my Header from JavaScript Data.
To generate I'm iterating through an Object.
Generating the HTML looks like:
for (const topic in templateTopic) {
if (Object.prototype.hasOwnProperty.call(templateTopic, topic)) {
const element = templateTopic[topic]
// console.log(element);
template += '<div class="col col-topic-element" id="' + element + '" onClick="filterTopic(' + element + ')">'
template += '<p>' + element + '</p>'
template += '</div>'
}
}
parent.innerHTML = '';
parent.insertAdjacentHTML('afterbegin', template);
When I inspect the Element it contain following strange data (Chrome Inspector Output):
<div id="topics" class="row">
<div class="col col-topic-element" id="film" onclick="filterTopic(film)">
<p>film</p>
</div>
<div class="col col-topic-element" id="photography" onclick="filterTopic(photography)">
<p>photography</p>
</div>
<div class="col col-topic-element" id="visual design" onclick="filterTopic(visual design)" data-kwdiaostructure=""0":"input","1":"submit#visual design##col col-topic-element####KwDiaoTagDIV","2":"visual design""
data-kwdiaohashid="input#submit#visual design##col col-topic-element####KwDiaoTagDIV#visual design">
<p>visual design</p>
</div>
</div>
How can I get rid of the data, because when I click on the last Element ("visual design"), the console throws an error and I can't add further code.
Console output after clicking the 3 generated Items:
I integrated Bootstrap 4 CDN and fontawesome.

Dynamically render object elements in HTML using JavaScript

let abilities = data.player_info.abilities
let summary = summarize_abiltiy(abilities)
console.log(summary)
document.getElementById("strength").append(
"<span class=" + "label label-success>" + summary.strength[0][0] + ":" + summary.strength[0][1] + "</span>")
I am trying to dynamically render items in the summary object.
As you can see, the Weak items are hard-coded right now and the JavaScript render just got appended as a string.
<div id="player_name" class="price"></div>
<div id="player_nation" class="lead"></div>
<center id="strength"><span><strong>Strong: </strong></span>
</center>
<center><span><strong>Weak: </strong></span>
<span class="label label-danger">HTML5/CSS</span>
<span class="label label-danger">HTML5/CSS</span>
<span class="label label-danger">HTML5/CSS</span>
<span class="label label-danger">HTML5/CSS</span>
<span class="label label-danger">HTML5/CSS</span>
</center>
Any ideas to fix it?
Nice question, as others have suggested innerHTML should solve your problem
document.getElementById('strength').innerHTML =
`<span class='label label-success'>${summary.strength1}:${summary.strength2}</span>`; //string literals
The new API append states that it is possible to use DOMString while appending
ParentNode.append() allows you to also append DOMString object, whereas Node.appendChild() only accepts Node objects.
So if you wish to remain with Node.append() i reckon the only way is to split it up further as below
var newSpan = document.createElement('span'); //create a node
newSpan.classList.add('label', 'label-success'); // manually add classes
newSpan.append(`${summary.strength1}:${summary.strength2}`);// here you can use append to append strings
document.getElementById('weak').append(newSpan); //can use append or appendChild here
#Tejasva's answer will remove <strong> tag... so better you use concate
document.getElementById("strength").innerHTML +=
"<span class=" + "label label-success>" + summary.strength[0][0] + ":" + summary.strength[0][1] + "</span>";
document.getElementById("strength").innerHTML +=
"<span class=" + "label label-success> Agility : 20 </span>";
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<center id="strength"><span><strong>Strong: </strong></span>
</center>
You may replace the static data with your dynamic data as per the requirement.

How do I display the values in a mySQL table in my website without using PHP?

Can't use PHP due to assignment restrictions. Just javascript, html and mySQL.
I've been trying to add a portfolio gallery to my website, with values from my 'food' table in mySQL being used in it. Portfolio entries would turn grey and show additional information when hovered over. Clicking on the navbar buttons would make only relevant portfolio entries show. The portfolio gallery would ideally look like this. (Hardcoded)
This is how my attempt went, with only my navbar showing and not my portfolio entries.
Attempted Portfolio Gallery
My SQL code behind the scenes for GET work properly, tested with Restlet Client, so I think the problem most likely has to do with the html code making use of those SQL codes. Can't figure out why though. Sorry if this is a stupid question, but any help would be appreciated!
Portfolio Entry HTML code (Hardcoded)
<div class="portfolio-item alacarte col-xs-12 col-sm-4 col-md-3">
<div class="recent-work-wrap">
<img class="img-responsive" src="images/portfolio/recent-new/hamncheese.png" alt="">
<div class="overlay">
<div class="recent-work-inner">
<h3>
Ham and Cheese Sandwich
</h3>
<p>Ham, Cheese, Brioche Bread
<br>$1</p>
<a class="preview" href="images/portfolio/full-new/hamncheese.png" rel="prettyPhoto">
<i class="fa fa-eye"></i> View</a>
</div>
</div>
</div>
</div>
SQL Attempt as a script in the < head> :
<script>
function displayFoods() {
var request = new XMLHttpRequest();
// The route pattern '/movies' is registered in the routeMovies.js file.
request.open("GET", "/food", true);
request.setRequestHeader("Content-Type", "application/json");
request.onload = function() {
// We create a 'movies' variable to store data of all movies retrieved
// from the server.
// All movies will be stored in the form of an array in the movies variable.
var foods = JSON.parse(request.responseText);
var totalFoods = foods.length;
// Get the HTML element of the div where id="movieListings" so that
// we can add HTML codes to display all the movies.
var listings = document.getElementById("foodListings");
// We use a for loop to traverse through the array of movies.
// For every movie, we get the name and picture.
for (var count = 0; count < totalFoods; count++) {
var name = foods[count].name;
var picture = foods[count].picture;
var foodType = foods[count].foodType;
var info = foods[count].info;
var price = foods[count].price;
// We create the HTML codes for displaying each movie and store in a variable 'movieItem'.
// We also insert each movie name and picture in the HTML codes.
var foodItem = '<div class="portfolio-item '+ foodType +' col-xs-12 col-sm-4 col-md-3"> \
<div class="recent-work-wrap"> \
<img class="img-responsive" src=" '+ picture +' " alt=""> \
<div class="overlay"> \
<div class="recent-work-inner"> \
<h3> \
'+ name +' \
</h3> \
<p> ' + info + ' \
<br>$1</p> \
<a class="preview" href=" ' + picture + ' " rel="prettyPhoto"> \
<i class="fa fa-eye"></i> View</a> \
</div> \
</div>\
</div>\
</div>';
// We use the built-in JavaScript function insertAdjacentHTML() which is from
// the HTML element object to insert the HTML codes.
listings.insertAdjacentHTML('beforeend', foodItem);
}
};
// Send the request to get info of all movies.
request.send();
}
</script>
and in the actual html after the navbar code...
<div class="row" onload="displayFood()">
<div class="portfolio-items" id="foodItem"></div>
</div>
I think that's about it for any relevant code. Again, thanks for any help!

how can I manipulate my HTML after reading my JSON file?

<script type="text/javascript">
window.alert = function(){};
var defaultCSS = document.getElementById('bootstrap-css');
function changeCSS(css){
if(css) $('head > link').filter(':first').replaceWith('<link rel="stylesheet" href="'+ css +'" type="text/css" />');
else $('head > link').filter(':first').replaceWith(defaultCSS);
}
$( document ).ready(function() {
$.getJSON("./data/data.json", function(json) {
console.log(json.length); // this will show the info it in firebug console
});
});
</script>
I know that json is my JSON object. I want to use that to manipulate my html
if it's the 1st item in my JSON object then
<div class="item active"> <!-- active only appears if it's the first item -->
<blockquote>
<div class="row">
<div class="col-sm-3 text-center">
<img class="img-circle" src="json[0].image" style="width: 100px;height:100px;">
</div>
<div class="col-sm-9">
<p>json[0].quote</p>
<small>json[0].person</small>
</div>
</div>
</blockquote>
</div>
and I want to repeat the above code n times
There are many ways to do this, but probably the easiest way would be to build a string and append it to whatever container you want it to live in.
$.getJSON("./data/data.json", function(json) {
$.each(json, function(data) {
var html = '<p>' + data.quote + '</p>' +
'<small>' + data.person + '</small>';
$('#MySuperSpecialDiv').append(html);
});
});
Please note that this won't scale well. If you are going to add much more markup than you already have, you should really consider some sort of templating alternative.
Also, if some one comes in behind you to maintain this project, you probably won't be their favorite person.

Loading large amounts of html in javascript

How can I load large amounts of HTML in javascript? I will show a snippet below. I want to get all the HTML into the "ALL HTML GOES HERE" space in the java. I know you can put smaller things like <h1>Hello!</h1> but I can't figure out how to get all of that into there with it working. Unless there is another way to do this let me know.
function validate() {
var x = $('#in').val();
if (navigator.userAgent.indexOf("Chrome") != -1) {
$('#id').html('ignore');
} else {
$('#id').html('ALL HTML GOES HERE');
}
}
window.onload = validate;
<div id="popup" class="overlay">
<div class="popup">
<a class="close" href="javascript:popupClose();">×</a>
<div class="content">
</div>
</div>
</div>
Instead of putting the HTML in a Javascript string, put it in the page's HTML, but hide it with display: none; style. Then you can copy it to #id.
function validate() {
var x = $('#in').val();
if (navigator.userAgent.indexOf("Chrome") != -1) {
$('#id').html('ignore');
} else {
$('#id').html($("#allhtml").html());
}
}
window.onload = validate;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="popup" class="overlay">
<div class="popup">
<a class="close" href="javascript:popupClose();">×</a>
<div class="content">
</div>
</div>
</div>
<div id="allhtml" style="display: none;">
<div>
ALL HTML GOES HERE
</div>
</div>
You can just pass it the entire string:
function validate() {
var x = $('#in').val();
var htmlString = '<div id="popup" class="overlay">';
htmlString += '<div class="popup">';
htmlString += '<a class="close" href="javascript:popupClose();">×</a>';
htmlString += '<div class="content"></div></div></div>';
if (navigator.userAgent.indexOf("Chrome") != -1) {
$('#id').html('ignore');
} else {
$('#id').html(htmlString);
}
if you don't want to write all html inside ' ' , you could load html with ajax, so first you would create file
allhtml.html
containg your html, and there instead of your:
$('#id').html..
you would use
$('#id').load('allhtml.html')
One option that can help:
You can put all the HTML in a separate HTML file and use JQuery's .load('anotherpage.html'....) method. Basically, you'd just call that like: $('#id).load('....');
Here's the documentation with examples
http://api.jquery.com/load/

Categories