Divs with same id error - javascript

<div id="tagTree1" class="span-6 border" style='width:280px;height:400px;overflow:auto;float:left;margin:10px; '>
<a class="tabheader" style="font-size:large">Data Type</a><br />
<div class="pane">Refine search by Data Type</div>
</div>
Above div(tagTree1) is present in a division ad.
<div id="newtagTree1" class="span-6 border" style='width:200px;height:400px;overflow:auto;float:left'>
<a class="tabheader"><strong>Geographic Location</strong></a><br />
<div class="pane"><strong>Refine search by geographic location</strong></div>
</div>
newTagTree1 division is present in another division search. But both have the same functionality to generate children divisions within them, which is written in a js file. All the children division generated dynamically in js file. Both of them uses same function to generate children divs. I am facing problem when i am using them in same page. If one works fine then the other doesn't. Can any one say me about the mistake i am doing in this?
Thanks in advance.
$.getJSON('/api/TagsApi/Children?id=800002', function (data) {
//$(tagDiv).empty();
$.each(data, function (i, item) {
$("#tagTree1").append(tagTabBuilder(item));
});
$("#tagTree1").tabs("#tagTree1 div.pane", { api: true, tabs: 'a', effect: 'slide', onClick: buildChildren, initialIndex: 0 });
});
function tagTabBuilder(tagData) {
var str = "<input type='checkbox' name='tagchkbox[]' value='" + tagData.ID + "' onClick='startQuery()' /><a class='tabheader '>" + tagData.NAME;
if (tagData.count == 0) {
str += " (<span class='el_count' id='t" + tagData.ID + "'>" + tagData.count + "</span>)" + "</a><br/>";
} else {
str += " (<span class='el_count' id='t" + tagData.ID + "'><strong>" + tagData.count + "</strong></span>)" + "</a><br/>";
}
str += "<div id='tid-" + tagData.ID + "' class='pane tag'><!--Loading subtags. . .<img src='/assets/modules/gaiaModule/shared/images/load-small.gif' />--></div>";
return str;
}

My guess would be that when they generate child divs, they're generating them with the same ID scheme. Thus, either of them can generate child divs just fine by itself, but when both of them are included, there is ID collision. The answer is to modify the child generation code to, for example, include the id of the parent div as the first portion of the id of the child div.
Alternately, if you dont' need them for other portions of the javascript, leave the child div ids out entirely. In general, I find that it's better to avoid the id attribute in generated nodes, and instead use classes or the like.

Related

How to Prevent TD from ending up on a new line?

I am dynamically creating a table through Javascript and I DO want the table to continue off the right side of the page. Doing this manually lets the table continue off, but once I feed this into a for loop the <td>s wrap into a second line in the rendered HTML, creating two or more table rows when they reach the end of the page.
<div id="panelindex" style="overflow:scroll;text-align:center;">
<table border="0">
<tr></tr>
</table>
</div>
This is inside a table of its own (no style formatting). Then the Javascript:
var q = Math.floor((1/numpanels)*500);
if(q>50) q=50;
panelindex.innerHTML = "<table border='0'><tr>"
for(i=0; i<numpanels; i=i+1)
{
panelindex.innerHTML = panelindex.innerHTML + "<td><div id='panel" + i + "' onclick='jumppage(" + i + ")' style='float:left;text-align:center;margin:8px;border-width:3;border-color:white;border-style:none;'><a href='#" + i + "'><img src='thumbnails.php?image=blowem" + zeroFill(i,2) + ".gif&GIF&tw=128&th=128&quality=" + q + "'>\n" +
"<br />" + i + "</a></div></td>\n";
}
panelindex.innerHTML = panelindex.innerHTML + "</tr></table>"
You may notice that there is a <div> in the <td> and that is so I can apply a border marking the panel. Without the <div> it seems I cannot do that, and there are some other undesired effects. Any ideas what I can do so that all the <td>s end up on one line rather than split to a new line?
Example of what I want: http://edwardleuf.org/comics/jwb/009-conmet
What is happening: https://jsfiddle.net/w4uh0a3j/7/
Click the Show link.
innerHTML does not hold the string value you assign to it.
It parses the value as HTML, creates a DOM from it, inserts it into the document and then, when you read it back, it converts that DOM back into HTML.
This means that the string you assign is subject to error recovery and normalisation. In particular, the end tags you omitted are fixed.
panelindex.innerHTML = "<table border='0'><tr>"
console.log(panelindex.innerHTML);
<div id="panelindex" style="overflow:scroll;text-align:center;">
<table border="0"><tr>
</tr></table>
</div>
So when you start appending more data to it:
panelindex.innerHTML = panelindex.innerHTML + "<td>etc etc
You end up with:
<table border="0"><tbody><tr></tr></tbody></table><td>etc etc
Store your data in a regular variable. Only assign it to .innerHTML once you have the complete HTML finished.
A better approach then that would be to forget about trying to build HTML by mashing strings together (which is error prone, especially once you start dealing with characters that need escaping in HTML) and use DOM (createElement, appendChild, etc) instead.
OK,here is fixed html and js code. It seems like innerHTML fixes missing closing when updating html before all the code is building the rest of innerHTML. This code works :
<div id="panelindex" style="overflow:scroll;text-align:center;">
</div>
and js code :
var numpanels = 100;
var q = Math.floor((1/numpanels)*500);
if(q>50) q=50;
panelindex.innerHTML = "<table border='0'><tr>";
var html = "<table border='0'><tr>";
for(i=0; i<numpanels; i=i+1) {
html += "<td><div id='panel" + i + "' onclick='jumppage(" + i + ")' style='float:left;text-align:center;margin:8px;border-width:3;border-color:white;border-style:none;'><a href='#" + i + "'><img src='thumbnails.php?image=blowem" + ".gif&GIF&tw=128&th=128&quality=" + q + "'>\n" +
"<br />" + i + "</a></div></td>";
}
html += "</tr></table>";
document.getElementById("panelindex").innerHTML = html;

Dynamically add array contents as new elements - JQuery

edit: Problem solved! I was modifying the page before it was loaded so the script didn't actually do anything. I fixed it now and it works. Thanks for the help, I'll have to chalk this one up to being new to jQuery and it's weirdness.
Long story short I'm trying to make a webpage that dynamically takes Article titles, thumbnail images, descriptions, and links to them, and creates a nicely formatted list on the page. I'm trying to accomplish this in jQuery and HTML5.
Here is the sample data that I'll be using to dynamically populate the page. For now formatting isn't important as I can do that later after it works at all.
<script>
var newsTitles = ["If It Ain't Broke, Fix It Anyways"];
var newsPics = ["images/thumbnail_small.png"];
var newsDescs = ["August 14th 2015<br/><b>If It Ain't Broke</b><br/>Author: Gill Yurick<br/><br/> Sometimes, a solution isn't the only one. So how do we justify changes to systems that don't need to be fixed or changed? I explore various systems from other successful card games and how their approaches to issues (be they successes or failures in the eyes of the deisgners) can help us create EC."];
var newsLinks = ["it_aint_broke-gill_popson.html"];
var newsIndex = 0;
var newsMax = 1;
The section of code where I'm trying to use the contents of the arrays above to dynamically fill elements.
<td style="height:500px;width:480px;background-color:#FFF7D7;padding:20px" colspan=2 id="article">
<h1>Articles</h1>
<!-- the column for each news peice add an element with the thumbnail, the title and teh desc -->
<script>
for(i = 0; i < newsMax; i++) {
$("#articleList").append("<h3 href="" newsLinks[i] + "">" + newsTitles[i] + "</h3>", "<img src=""newsPics[i] + "">","<p>" + newsDesc[i] + "</p>", ); $("div").append("hello");
}
</script>
<div id="articleList">
HELLO
</div>
</td>
Here is what it ends up looking like, I can post more info if needed as I am aware this may not be clear enough to fully explain my problem but I am unable to determine that. Thank you in advance.
try this
for(i = 0; i < newsMax; i++) {
$("#articleList").append("<h3 href=""+ newsLinks[i] + "">" + newsTitles[i] + "</h3>, <img src=""+newsPics[i] + "">, <p>" + newsDescs[i] + "</p>" ); $("div").append("hello");
}
Concatation issue + typo for newsDescs
The following string is invalid html and is missing a +
"<h3 href="" newsLinks[i] + "">"
You need to use proper quotes for html attributes, not &quote;
Try
"<h3 href='" + newsLinks[i] + "'>"
OR
"<h3 href=\"" + newsLinks[i] + "\">" // `\` used to escape same type quote
Personally I prefer opening/closing html strings with single quotes but either will work
Note tht you should be getting a syntax error thrown in dev tools console which would have helped you locate problems
for(i = 0; i < newsMax; i++) {
$("#articleList").append("<h3 href='" + newsLinks[i] + "'>" + newsTitles[i] + "</h3>");
$("#articleList").append("<img src='" + newsPics[i] + "'>","<p>" + newsDesc[i] + "</p>" );
}

Render the Xml file having controls layout into HTML5 page

I have the following xml file with the controls information to render into HTML page.
The contents are like:
<control type="panel">
<panel id="p1">
<button id="b1">
<value>TEST</value>
</button>
<textbox id="t1">
<text>HELLO</text>
</textbox>
</panel>
<control>
This has to rendered on the fly into a div with a panel containing one button and one textbox.The contents of xml are known only at runtime.It can be anything like only a button or a dropdown list information.How would one go about approaching this problem.A generic algorithm(probably using jquery) would be really helpful.
For something generic, your XML would need to be generic or conformant to a convention along the lines of "XML to HTML form convention". I know of no such thing. :)
It seems easy enough to handle. Here's an example of how I'm handling your XML example.
$(function() {
// Data setup (I assume you'd be getting this from AJAX)
var xml = '<control type="panel">' +
'<panel id="p1">' +
'<button id="b1">' +
'<value>TEST</value>' +
'</button>' +
'<textbox id="t1">' +
'<text>HELLO</text>' +
'</textbox>' +
'</panel>' +
'</control>';
// Convert to jQuery XML object
var xml = $($.parseXML(xml));
// Set parent
var parent = $('#control');
// Handle elements
xml.find('panel').children().each(function() {
var tag = $(this)[0].tagName;
switch (tag) {
case 'button':
parent.append('<button id="' +
$(this).attr('id') + '">' +
$(this).find('value').text() +
'</button>');
break;
case 'textbox':
parent.append('<input type="text" id="' +
$(this).attr('id') +
'" value="' +
$(this).find('text').text() +
'" />');
break;
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="control"></div>
Of course, you could modify this as necessary, add new element handling, change the way it's added to the parent, etc. etc. I hope it helps.

Wrap each list array in a Tag

I am trying to get each Post lists wrapped in the href so it can be clicked on. Basically when I try to click on each Posts, it does not work until I hover my mouse close to the top of each posts before it works.
Below is my code and also an image of what I mean:
JS:
function getPosts(data) {
var $output = $('<ul class="posts" data-role="listview" data-filter="true">')
$.each(data.posts,function(i, val) {
$('<li><a href="#devotionpost" onclick="showPost(' + val.id + ')"</a>').append([$("<h3>", {html: val.title}),$("<p>", {html: val.excerpt})]).appendTo($output);
if ( i == 3 ) return false;
// return (postlimit-- > 1);
});
$('#postlist').empty().append($output);
}
function showPost(id) {
$('#mypost').html('<span class="img_spin">Loading post...</span>');
$.getJSON('http://howtodeployit.com/category/daily-devotion/?json=get_post&post_id=' + id + '&callback=?', function(data) {
var posts='';
posts += '<h3>' + data.post.title + '</h3>';
posts += data.post.content;
$('#mypost').html(posts);
});
}
Image:
If you look at the image, when i hover my mouse close to the top edge of the Post, then the URL at the bottom shows and that works but any where else does not work.
From looking at the Chrome Elements tab in this demo the JavaScript is generating invalid HTML because of mismatched closing elements.
Using an example posts of var posts = { "posts" : [ {"id":"1", "title":"lorem", "excerpt":"foo"}, {"id":"2", "title":"ipsum", "excerpt":"bar"} ] }
This '<li><a href="#devotionpost" onclick="showPost(' + val.id + ')"</a>' is resulting in the broken first child of the following <li>:
<li>
<a href="#devotionpost" onclick="showPost(1)" < a></a>
<h3>lorem</h3>
<p>foo</p>
</li>
Depending on exactly what you want to wrap in the anchor element, you could just build the post <li> like in this updated demo or see code below:
$.each(data.posts,function(i, val) {
$output.append('<li><h3>' + val.title + '</h3><p>' + val.excerpt + '</p></li>');
});
Or if you want to have a little less string concatenation, you could use .wrapInner()
$.each(data.posts,function(i, val) {
var $post = $('<li><h3>' + val.title + '</h3><p>' + val.excerpt + '</p></li>');
$post.wrapInner('');
$output.append($post);
});
Or keeping your .append() approach:
$.each(data.posts,function(i, val) {
var $post = $('<li/>').append([$("<h3>", {html: val.title}),$("<p>", {html: val.excerpt})]).wrapInner('');
$output.append($post);
});
Note: The string concatenation approach, combined with a single .append() is the best performing code.
By the looks of it, your lists are floating. You should use a clearfix technique to make "A" element box include the list. You also should know that by standard "A" elements are not allowed to contain block elements and as far as internet explorer 9 (didn't check in 10 or 11) "A" will not work the way you intended.
Possible workaround:
<div style="position:relative">
<ul>
<li></li>
<ul>
<a style="position:absolute;display:block;top:0;bottom:0;left:0:right:0;" href="#"></a>
<div>

jQuery "undefined" prints when appending to html element

I'm making a jQuery MP3 player. The song structure is first generated (including the information about the song), and then the structure is appended to a div using jQuery like this:
function loadFromPlaylist(playlist) {
var songsStructure;
for (var i=0; i<playlist.length; i++) {
songsStructure +=
"<div id='song" + i + "'>" +
"<span class='mpPlaylistArtist'>" + playlist[i].artist + "</span>" +
"<span class='mpPlaylistSong'>" + playlist[i].song + "</span>" +
"<span class='mpPlaylistAlbum'>" + playlist[i].album + "</span>" +
"</div>";
}
$('#mpTracks').append(songsStructure);
}
This works perfectly except for one thing. When the items are displayed in the browser, a string ("undefined") is printed above the songs, like so:
<div id="mpTracks">
"undefined"
<div id="song0">...</div>
<div id="song1">...</div>
</div>
Googling this problem yielded alot of related problems but that didn't help me.
Does anyone know what the problem might be?
Initialize your variable to an empty string, before using it:
var songsStructure = '';
You did not set an initial value, so it is set to undefined. According to JS rules for concatination, this undefinedis then concatenated with the strings generated by the for loop leading to your result.
You have to initialize the songsStructure variable.
Write
function loadFromPlaylist(playlist) {
var songsStructure="";
and your problem will be solved.

Categories