HTML DOM have data I didn't add through Javascript - 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.

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!

JQM - Add image to collapsible header dynamically

I have a collapsible set for days of the week, with user's activities inside it that represented as a listview inside the collapsible-set.
<div data-role="collapsible-set" id="calCol" data-collapsed-icon="arrow-d" data-collapsed="true" data-iconpos="right">
<div data-role="collapsible">
<h1 id="day1Header">Sunday<img src="#" /></h1>
<ul id="day1" data-role="listview">
</ul>
</div>
<div data-role="collapsible">
<h1>Monday</h1>
<ul id="day2" data-role="listview">
</ul>
</div>
...
All the content for the user's activities i take from my database so i insert all my content dynamically like this:
var userActivitiesObj = JSON.parse(data.d);
for (var i = 0; i < userActivitiesObj.length; i++) {
for (var j = 0; j < userActivitiesObj[i].time.length; j++) {
var listItem = "<li style='background-color: " + userActivitiesObj[i].hobColor + ";'>";
listItem += userActivitiesObj[i].actName + " - " + userActivitiesObj[i].actAddress + " - ";
listItem += userActivitiesObj[i].time[j].startTime + "-" + userActivitiesObj[i].time[j].endTime;
listItem += " (" + userActivitiesObj[i].time[j].audiance + ")</li>";
$("#day" + userActivitiesObj[i].time[j].day).append(listItem);
$("#day" + userActivitiesObj[i].time[j].day).listview("refresh");
}
}
One last thing that left for me to do is to add image of every activity to the header of that day.
When i have tried to do it in html, it worked flawlessly:
<h1 id="day1Header">Sunday<img src="#" /></h1>
but when trying to do it dynamically, it doesn't work correctly.
That what i have tried to do:
$("#day1Header").html($("#day1Header").html()+"<img src='#'");
and:
$("#day1Header").append("<img src='#'");
I know that i am missing here something like the .list("refresh") function, but i have no idea what is that.
jQuery Mobile adds an anchor tag with class ui-collapsible-heading-toggle within the header and places the collapsible title there. So you can remove previous images and append the new image like this:
$("#day1Header .ui-collapsible-heading-toggle img").remove();
$("#day1Header .ui-collapsible-heading-toggle").append('<img src="https://placeimg.com/44/22/tech" />');
DEMO

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>

Issue adding a unique ID to an HTML attribute using jQuery

I am having an issue changing the ID of HTML attributes using JQuery.
This is what I have been using:
$(document).ready(function () {
$('.hiddenDiv').each(function (i) {
$(this).attr("id", "title" + (i + 1));
});
This the HTML:
<div id="Foo">
<div class="title"></div>
<hr></hr>
<div class="hiddenDiv" style="display:none;"></div>
<hr></hr>
<div class="title"></div>
<hr></hr>
<div class="hiddenDiv" style="display:none;"></div>
</div>
I am producing the HTML using another JQuery script that creates it, iterating through an object creating a title and hiddenDiv divs for each element that exists in the object.
jQuery Script that produces the HTML:
$('#Foo').append('<div class="hiddenDiv" style="display:none;">' + foo[0].Content + '<br>' + 'Address: ' + foo[0].Address + '</div><br><hr>');
Both scripts execute when the document is ready.
Looks like elements are not created on DOM ready. You need to add the ids to them just after appending the content. like this:
$('#Foo').append('<div class="hiddenDiv" style="display:none;">' + foo[0].Content + '<br>' + 'Address: ' + foo[0].Address + '</div><br><hr>');
$('.hiddenDiv').each(function (i) {
$(this).attr("id", "title" + (i + 1));
});
Demo

Obfuscate html content dynamically

I am developing a web widget, so I need to protect some sources for image and audio tags. Also I am putting the html content through a jquery function. Is there any javascript/jquery methods to obfuscate an entire div dynamically ? Following is my code :
function getHTML(){
var html = '<div class="col-xs-8 col-xs-offset-4 col-md-10 col-md-offset-2">' +
'<div style="margin-right: 16px;">' +
'<audio id="audio_widget" src="mysource/data1.mp3"></audio>' +
'<audio class="alternate_audio" src="mysource/data2.mp3"></audio>' +
'</div>' +
'</div>'+
'<ul id="albumList" class="image-list">'+
'<li><img src="mysource/image1.jpg" alt="" width="100" height="100"></li>'+
'<li><img src="mysource/image2.jpg" alt="" width="100" height="100"></li>'+
'</ul>';
//Through this function I want to obfuscate entire 'html' content.
var encoded = someFunction(html);
return encoded;
}

Categories