Building dynamic links in Javascript - javascript

I have this code below:
for (var index in mv.exifImages) {
var p = document.createElement("p");
var oText = document.createTextNode("link" + index);
p.appendChild(oText);
var info = mv.exifImages[index];
p.onclick = function() {
mv.openNewWindow(info);
};
ele.appendChild(p);
}
I want to create paragraph elements and when I click on them open a new window with correct array content. But I am anable to biuld different links. All my paragraphs open a new window with the array contents at the last index. Is there a trick around this?

I think this should work:
for (var index in mv.exifImages) {
var p = document.createElement("p");
var oText = document.createTextNode("link" + index);
p.setAttribute("indexAttr",index);
p.appendChild(oText);
p.onclick = function() {
mv.openNewWindow(mv.exifImages[this.getAttribute("indexAttr")]);
};
ele.appendChild(p);
}

The following works...
for (var index in mv.exifImages) {
var p = document.createElement("p");
var oText = document.createTextNode("link" + index);
p.appendChild(oText);
var info = mv.exifImages[index];
p.onclick = openNew(info);
ele.appendChild(p);
}
function openNew(a) {
return function() {
mv.openNewWindow(a);
}
}

Related

How do you send a list of a node's children ids using thymeleaf?

I have a function that adds badges to a div by selecting items from a dropdown list.
I'm adding badges using this function added to the dropdown list onclick event:
function addBadge(parent, badgeId, value){
var elem = document.getElementById(parent);
var currentTaxiways = elem.children;
var alreadyExists = false;
for(var i = 0; i < currentTaxiways.length; i++){
if(badgeId === currentTaxiways[i].id){
alreadyExists = true;
}
}
if(!alreadyExists) {
var newBadge = document.createElement("span");
newBadge.classList.add("badge");
newBadge.classList.add("badge-primary");
newBadge.classList.add("bg-secondary");
newBadge.id = badgeId;
var node = document.createTextNode(value);
newBadge.appendChild(node);
newBadge.innerHTML += " ";
var deleteButton = document.createElement("a");
deleteButton.href = "#";
deleteButton.classList.add("x-btn");
deleteButton.onclick = function delBadge() {
deleteBadge(newBadge.id);
};
var node2 = document.createTextNode("X");
deleteButton.appendChild(node2);
newBadge.appendChild(deleteButton);
elem.appendChild(newBadge);
}
}
And the function for deleting the badges is this one:
function deleteBadge(badge){
var elem = document.getElementById(badge);
elem.parentNode.removeChild(elem);
}
How do I send the list of ids of all the badges added to the div to my controller using thymeleaf when the form is submitted?

Unable to parse json using javascript

I have a json which i'm trying to parse it using javascript. Iteration count and the pages getting appended to it are going to be dynamic.
Expected Result
Just like the above image i'm able to take dynamic iteration keys from the below mentioned json.
Iteration.json
{
"count":[
{
"iteration1":[
{
"PageName":"T01_Launch"
},
{
"PageName":"T02_Login"
}
]
},
{
"iteration2":[
{
"PageName":"T01_Launch"
},
{
"PageName":"T02_Login"
}
]
}
]
}
When i click on iteration it has to populate the corresponding pagenames for that particular iteration as shown in expected result image. But what i get actually is (refer the image below):
Please find the code that i tried:
var pagenamearray = [];
$.getJSON("iteration.json", function(json) {
var hits = json.count;
var iterations, tnname, iteration;
for (var k in hits) {
var value;
if (hits.hasOwnProperty(k)) {
value = hits[k];
var iteratearray = [];
for (var j in value) {
if (value.hasOwnProperty(j)) {
j;
var check = value[j];
for (var i in check) {
if (check.hasOwnProperty(i)) {
var test = check[i];
for (var t in test) {
if (test.hasOwnProperty(t)) {
var pagename = JSON.stringify(t)
var arr = []
if (pagename.includes("PageName")) {
//alert("Key is " +pagename + ", value is" + JSON.stringify(test[t]));
for (var it = 0; it < hits.length; it++) {
if ((Object.keys(hits[it])).includes(j)) {
var pagenamevalue = test[t];
arr[it] = [];
arr.push(pagenamevalue);
}
}
}
//alert(arr)
}
pagenamearray.push(arr);
}
}
}
}
var row = document.createElement('div');
row.setAttribute("class", "row");
row.setAttribute("id", j)
var gridWidth = document.createElement('div');
gridWidth.setAttribute("class", "col-lg-12");
var panelRoot = document.createElement('div');
panelRoot.setAttribute("class", "panel panel-default");
var panelHeading = document.createElement('div');
panelHeading.setAttribute("class", "panel-heading");
var heading3 = document.createElement('a');
heading3.setAttribute("class", "panel-title");
var icon = document.createElement('i');
icon.setAttribute("class", "fa fa-long-arrow-right fa-fw");
heading3.appendChild(icon);
heading3.innerHTML = j;
heading3.setAttribute("onclick", "doit('" + j + "');");
panelHeading.appendChild(heading3);
/* var panelBody=document.createElement('div');
panelBody.setAttribute("class","panel-body");
panelBody.setAttribute("id","panellinks");*/
panelRoot.appendChild(panelHeading);
// panelRoot.appendChild(panelBody)
gridWidth.appendChild(panelRoot);
row.appendChild(gridWidth);
document.getElementById("analysis").appendChild(row);
}
}
}
});
function doit(value) {
var ul = document.getElementById(value);
if (ul != undefined) {
$("#" + "expandlinks").remove();
$("#" + value + value).remove();
}
var accordion = document.getElementById(value);
var panelBody = document.createElement('div');
panelBody.setAttribute("class", "panel-body");
panelBody.setAttribute("id", "expandlinks")
var tablediv = document.createElement('div')
var tablelink = document.createElement('a');
tablediv.appendChild(tablelink);
var graphdiv = document.createElement('div')
var graphlink = document.createElement('a');
graphdiv.appendChild(graphlink);
var recommndiv = document.createElement('div');
var recommendlink = document.createElement('a');
recommndiv.appendChild(recommendlink)
//alert(pagenamearray.length)
tablelink.innerHTML = pagenamearray;
/*graphlink.innerHTML="Timeline View";
recommendlink.innerHTML="Recommendations";*/
panelBody.appendChild(tablediv);
panelBody.appendChild(recommndiv);
panelBody.appendChild(graphdiv);
accordion.appendChild(panelBody);
}
Any advise on how to achieve this would be of great help. Thanks in advance.
I think the problem is how you assign the pagenamearray to tablelink.innerHTML. This converts the array to a string, converting all elements in the array to a string too and separating them by a comma each. However, your pagenamearray contains some empty arrays too; these will convert to an empty string in the process, but will still have a comma before and after them.
In your example code above, the pagenamearray will end up with a value of [[[],"T01_Launch"],[[],"T02_Login"],[null,[],"T01_Launch"],[null,[],"T02_Login"]] - when converted to a String, this will result in ",T01_Launch,,T02_Login,,,T01_Launch,,,T02_Login". So instead of assigning it to the innerHTML value directly, you'll first have to filter out the empty arrays and null values.

Incrementing this.clicks from a function inside a prototype function

This code displays two cats and the number of times each cat is clicked, how can I increment the .clicks property of each cat from inside the Cat.prototype.clickInc() method?
$(document).ready(function() {
var cats = [];
var Cat = function(id, image_path) {
this.id = id;
this.image_path = image_path;
this.clicks = 0;
};
Cat.prototype.clickInc = function() {
$('#'+this.id).click(function(){
this.clicks++;
return this.clicks;
});
};//use a closure here
var poly = new Cat("poly", "poly.jpg");
var chewie = new Cat("chewie", "chewie.jpg");
cats.push(poly);
cats.push(chewie);
for(i=0; i<cats.length; i++)
{
var catInfo = '<div class="cats"><div id="'+cats[i].id+'"><img src='+cats[i].image_path+'><h3>'+cats[i].id+'</h3></div><div class="clickNos"><span ="label">Number of clicks</span><span class="clicks">'+cats[i].clicks+'</span></div></div>';
$("#container").append(catInfo);
cats[i].clickInc();
}
});
this is not Cat within .click() handler. Also, you cannot return from an event handler. Use .next(".clickNos") with .find(".clicks") to select next .clicks element relative to clicked <img> element; set .html() of matched element to .clicks property of Cat instance.
Cat.prototype.clickInc = function() {
var _cat = this;
$('#' + this.id).click(function() {
_cat.clicks++;
$(this).next(".clickNos").find(".clicks").html(" " +_cat.clicks);
});
};
jsfiddle https://jsfiddle.net/9cykvbyv/1/

Pull Image Url From RSS FEED

I'm using the following code to display to parse an RSS feed via Javascript and Google Feed API into HTML. Is it possible to grab an image from the RSS feed? It is working fine fro the title, snippet, date and link. I just need the URL for the image as well.
function myGetElementsByClassName(selector) {
if ( document.getElementsByClassName ) {
return document.getElementsByClassName(selector);
}
var returnList = new Array();
var nodes = document.getElementsByTagName('div');
var max = nodes.length;
for ( var i = 0; i < max; i++ ) {
if ( nodes[i].className == selector ) {
returnList[returnList.length] = nodes[i];
}
}
return returnList;
}
var rssReader = {
containers : null,
// initialization function
init : function(selector) {
containers = myGetElementsByClassName(selector);
for(i=0;i<containers.length;i++){
// getting necessary variables
var rssUrl = containers[i].getAttribute('rss_url');
var num = containers[i].getAttribute('rss_num');
var id = containers[i].getAttribute('id');
// creating temp scripts which will help us to transform XML (RSS) to JSON
var url = encodeURIComponent(rssUrl);
var googUrl = 'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&num='+num+'&q='+url+'&callback=rssReader.parse&context='+id;
var script = document.createElement('script');
script.setAttribute('type','text/javascript');
script.setAttribute('charset','utf-8');
script.setAttribute('src',googUrl);
containers[i].appendChild(script);
}
},
// parsing of results by google
parse : function(context, data) {
var container = document.getElementById(context);
container.innerHTML = '';
// creating list of elements
var mainList = document.createElement('ul');
// also creating its childs (subitems)
var entries = data.feed.entries;
for (var i=0; i<entries.length; i++) {
var listItem = document.createElement('li');
var title = entries[i].title;
var publishedDate = entries[i]. publishedDate;
var contentSnippet = entries[i].contentSnippet;
var contentSnippetText = document.createTextNode(contentSnippet);
var mediaGroup = entries[i].mediaGroup;
var link = document.createElement('a');
link.setAttribute('href', entries[i].link);
link.setAttribute('target','_blank');
var text = document.createTextNode(title);
link.appendChild(text);
var text = document.createTextNode(publishedDate);
link.appendChild(text);
var text = document.createTextNode(mediaGroup);
link.appendChild(text);
// add link to list item
listItem.appendChild(link);
var desc = document.createElement('p');
desc.appendChild(contentSnippetText);
// add description to list item
listItem.appendChild(desc);
// adding list item to main list
mainList.appendChild(listItem);
}
container.appendChild(mainList);
}
};
window.onload = function() {
rssReader.init('post_results');
}
<div class="post_results" id="post_results2" rss_num="2" rss_url="http://www.feed.com/feed">
<div class="loading_rss">
<img alt="Loading..." src="images/loading.gif" />
</div>
</div>
I was able to pull the content (which houses the image tag) with: var
content = entries[i].content;
And parse that to get just the image using this:
var input = content;
var div = document.createElement('div');
div.innerHTML = input;
var img = div.getElementsByTagName('img')[0];

mapping Json data and adding data attr

I have a difficulty with mapping my my Json data. I would like to add data attr to each div with .name class. So as the result is like that:
<div class="name" data-key="sth"> sty</div>
Key can be got like that: ['streme'].key
here is my buggy JS:
function getExistingLinks() {
$.post( "http://0.0.0.0:9292/api/links", function( data ) {
var names = data.map(function (i) {
return i['link'].name
});
var keys = data.map(function (i) {
return i['link'].key
});
var container = document.querySelector(".link-names");
names.forEach(function(name) {
var div = document.createElement('div');
div.innerHTML = name;
$('div').addClass("name");
// $('div').each( function(index) {
$('div')[index].data("key") = keys[index];
}
container.appendChild(div);
});
});
return false;
}
names.forEach(function(name,index) {
var div = document.createElement('div');
div.innerHTML = name;
$(div).addClass("name");
$(div).data("key") = keys[index];
});
You need to remove the quotes in the $() selector!
As per your comment, may be try doing like:
var i = 0;
names.forEach(function(name) {
var div = document.createElement('div');
div.innerHTML = name;
$('div').addClass("name");
$('div').data("key", keys[i]);
container.appendChild(div);
i++;
});
the preferred method is to only add to the DOM once, as adding to the DOM will cause a redraw on each.
psuedo code as not sure what name represents in your innerHTML:
var divs = [];
for (var i, len = names.length; i < len; i++) {
divs.push($(''+name+'').data("key", keys[i]));
}
$container.append(divs);
http://codepen.io/jsdev/pen/2866265243563efd79cf05a5b12202b3
try something like this
$('.name').data('key') //will give you sth

Categories

Resources