Dynamically render object elements in HTML using JavaScript - 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.

Related

How to create HTML via Javascript from JSON input?

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!

jQuery can't catch the parent element

I am trying to access the parent element up to the button element to modify its css. I can access the span element via id. But when I try to go to the parent img it says undefined
Here is my html code
<button type="button" class="buttonLike">\
<img src = "../Image/thumbsUp.png" clas="test">\
<span class="postID" id=' + idPost + '>' + likesPost + '</span>\
</img>\
</button>\
and here is my jquery code that access the span element
$.each(result, function (index,data) {
var liked = data.liked;
if (liked == true) {
console.log($("#" + postId).parent("img").attr("src"));
}
});
How can i do this right.
img element is self-closing. try this:
<button type="button" class="buttonLike">\
<img src = "../Image/thumbsUp.png" clas="test">
<span class="postID" id=' + idPost + '>' + likesPost + '</span>\
</button>
and get it with jquery:
console.log($("#" + postId).parent().find("img").attr("src"));
I think you should not wrap the span inside the img. that will make more easy for you. But if you still want to. try this.
$("#postId").closest("img");
try using this
.parent().find('img').attr('src')
console.log($("#idPost").parent().find('img').attr('src'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" class="buttonLike">
<img src = "Image/thumbsUp.png" class="test">
<span class="postID" id='idPost'>likesPost </span>
</button>
I have closed the image and made the span as sibling of parent;
In this code snippet I have provided both jquery approach and pure js approach. Hope this helps.
//jquery approach
console.log($(".postID").siblings('.test').attr("src"));
//pure js
console.log(document.getElementsByClassName("postID")[0].previousElementSibling.getAttribute('src'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" class="buttonLike">
<img class="test" src="http://cdn3-www.dogtime.com/assets/uploads/gallery/goldador-dog-breed-pictures/puppy-1.jpg"/>
<span class="postID" id=' + idPost + '>' + likesPost + '</span>
</button>

how to hide tool tip in js

I have tooltip for each table row to show edit options. I make it visible using this code:
function popupFunction(p) {
var popup = document.getElementById("sp" + p);
popup.classList.toggle("show");
}
It's working well. But now the problem is how to hide it if I click any other places?
Here is my html:
<div class='popup' id='eds'>
<i class='fa fa-ellipsis-v' id =" + values.items[i].id + " onclick='popupFunction(this.id)'></i>
<span class='popuptext' id =sp" + values.items[i].id + ">
<div onclick='edit(this.id)' id =ed" + values.items[i].id + ">Edit</div>
<br/>
<div onclick='deleteFunction(this.id)' id =de" + values.items[i].id + ">Delete</div>
</span>
</div>
if show class makes an element to be rendred as tooltip, then removing it, should hide it.
document.getElementById(some_id).classList.remove("show")
should do the trick, i believe.

How to append a span tag inside another span tag in jquery?

I have the following code in jquery in which I am trying to add a child under a parent span tag:
jquery
var branchName = $(this).closest('tr').find('#adjNcmcompanyNameId').text();
var branchId = $(this).closest('tr').find('#adjNCMBranchIdForSearch').text();
var branchRecord = $(this).parents().find('#resultsection');
branchRecordSpan = ("<span class='multiselectContainer'></span>");
branchRecordSpan.append("<span class='indivSelectedText'>" + branchName + "</span>");
branchRecordSpan.append("<input class='indivSelectedValue' type='hidden' value=" + branchId + ">");
branchRecordSpan.append("<strong class='alert-pink'><i class='fa fa-chevron-left fa-lg'></i></strong>");
branchRecordSpan.append("</span>");
branchRecordSpan.append("<br/>");
html that I am trying to get
<div id="resultsection">
<span class="multiselectContainer" id=
"c85a47e3-40c0-48e1-95f0-89dd761dbb56"><span class=
"indivSelectedText">MY BRANCH</span> <input class="indivSelectedValue"
type="hidden" value="183424"> <strong class="alert-warning"><i class=
"fa fa-chevron-left fa-lg"></i> <i class="fa fa-database"></i>
,DATAHUB/ 8683403</strong> <a class="fa fa-times-circle labelclose"
href="#"></a></span><br>
</div>
Since all the content are under the multiselectContainer span class, I am trying to generate html dynamically using append and I am failing.
When I try to append under branchRecordSpan, it is throwing an error as it is not a function. I am not able to create child for the "multiseleccontainer" span class.
How can I create a span tag dynamically under another span tag? Please help.
Do it in stages.
x = $('<span>parent span</span>');
x.append('<span>new child span</span>');
someparent.append(x);
Or just do it directly:
x = $('<span>parent<span>child</span></span>');
The second option is generally more efficient. Every time you .append() something to the DOM, there's fair amount of background work to parse/modify/re-render/etc... It's generally best to build html as a string, then insert it into the DOM in one big chunk, rather than a series of smaller chunks.
You forgot a dollar sign here:
branchRecordSpan = ("<span class='multiselectContainer'></span>");

JQuery: Unable to get property from each img in a list of images

I'm trying to create a snippet of HTML, and iterate through each image within that snippet and apply a listener function and modify the image. However, using JQuery's .each() function is not allowing me to use functions such as .prop() to get/set image attributes. How can I apply functions such as .prop() to elements iterated over by the .each() function.
//formatImg simply returns a URL to the resource
var images = '<div class="flex-row">\
<div class="img">\
<img class="img-cover" data-src="' + formatImg(gallery.posts[0].image, 'medium') + '">\
</div>\
<div class="img">\
<img class="img-cover" data-src="' + formatImg(gallery.posts[1].image, 'medium') + '">\
</div>\
</div>';
var location = gallery.posts[0].location.address || 'No Location';
var elem = $('<div class="col-xs-6 col-md-3 tile story">\
<div class="tile-body">\
<div class="frame"></div>\
<div class="hover">\
<p class="md-type-body1">' + (gallery.caption || '') + '</p>\
<ul class="md-type-body2">\
<li>' + gallery.posts.length + (gallery.posts.length == 1 ? ' photo' : ' photos') +'</li>\
</ul>\
</div>\
' + images + '\
</div>\
<div class="tile-foot">\
<div class="hover">\
See all\
<!--<span class="mdi mdi-library-plus icon pull-right"></span>-->\
<!--<span class="mdi mdi-download icon toggle-edit toggler pull-right"></span>-->\
</div>\
<div>\
<div class="ellipses">\
<span class="md-type-body2">' + location + '</span>\
<span class="md-type-caption">' + getTimeAgo(new Date().getTime(), gallery.time_created) +'</span>\
</div>\
</div>\
</div>\
</div>'
);
elem.find('img.img-cover').each(function(){
_this = $(this);
console.log(_this.prop('data-src'));
attachOnImageLoadError(_this);
_this.prop('src',_this.prop('data-src'));
});
The console.log(_this.prop('data-src')) from within each, it returns undefined for every image.
Your problem has nothing to do with each(). Your problem is that you're trying to use prop() to handle HTML5 data attributes.
"data-src" is not an HTML property, therefore _this.prop('data-src') returns null. You would run into the same problem if you were using prop() to try to write to a data-src attribute.
Instead, to read a data attribute named data-src using jquery, use data(). So use _this.data('src').
See https://api.jquery.com/data/#data-html5 for more help.
I have created a simple script below that may help you to make it work:
var images = '<div class="flex-row">\
<div class="img">\
<img class="img-cover" data-src="img-1" />\
</div>\
<div class="img">\
<img class="img-cover" data-src="img-2">\
</div>\
</div>';
$(images).find('img.img-cover').each(function() {
alert($(this).data('src'))
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Categories