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 "e;
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>" );
}
Related
I've hit a roadblock I just can't get past after 5+ hours of fiddling. Basically what I'm trying to do is take responses from my API (a recipe search tool) and stick each individual recipe into its own card, having 2 cards side by side all the way down the page. The responses include various info about the recipe to be placed dynamically into each card, but everything I've tried working off the Doc's has just broken my page completely.
My JS (edited to remove a couple chars from my API key, sorry but it's a trial):
//On Index page this function takes search bar input and gives ten results for recipes
function createRecipe() {
var mealName = $("#recipeInput").val().trim();
$.ajax({
url: "https://api.edamam.com/search?q=" + mealName + "&app_id=70e00e26&app_key=6c683b56a399b435d00ee3100c0ca",
method: "GET"
}).then(function(response) {
for (i = 0; i < response.hits.length; i++) {
var newDiv = $("#recipeReveal");
newDiv.append("<div class='card col-lg-4 col-md-5 col-sm-10' style=''>")
.append("<div class='card-body'>")
.append("<h5>" + response.hits[i].recipe.label + "</h5>")
.append("<img class='card-img-top'src='" + response.hits[i].recipe.image + "' alt='Recipe Picture'></img>")
.append("<p class='card-text'>Full recipe instructions can be found at: <a href='" + response.hits[i].recipe.url + "'>" + response.hits[i].recipe.url + "</a></p>")
.append("</div>")
.append("<ul class='list-group list-group-flush'>");
for (j = 0; j < response.hits[i].recipe.ingredients.length; j++) {
newDiv.append("<li class='list-group-item'>" + response.hits[i].recipe.ingredients[j].text + "</li>");
}
newDiv.append("</ul>")
.append("<div class='card-body'>")
.append("<button id='result" + (i + 1) + "' onclick='saveRecipe(" + (i) + ")'>Save Recipe</button>")
.append("</div></div>");
}
queriedRecipe0 = (response.hits[0].recipe.uri);
queriedRecipe1 = (response.hits[1].recipe.uri);
queriedRecipe2 = (response.hits[2].recipe.uri);
queriedRecipe3 = (response.hits[3].recipe.uri);
queriedRecipe4 = (response.hits[4].recipe.uri);
queriedRecipe5 = (response.hits[5].recipe.uri);
queriedRecipe6 = (response.hits[6].recipe.uri);
queriedRecipe7 = (response.hits[7].recipe.uri);
queriedRecipe8 = (response.hits[8].recipe.uri);
queriedRecipe9 = (response.hits[9].recipe.uri);
})
}
This is posting into a div with the appropriate ID "recipeReveal", i thought I had it working but it turns out I just made one really long container with a tiny little card at the top that you can't even see. The ideal situation would be to have each recipe in its own card, along with img response, URL, ingredient list, button, etc. If I can get them into individual cards I definitely think I can knock out the CSS/ Grid system aspects easily. Just the JQuery that's getting me.
PS - Any resources/ easy to understand documentation on this subject is also appreciated if you don't have the time to really dive into this one! Thank you. `
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;
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.
I have the following snippet of code:
$("#QnAList").append("<div id=qdiv" + i + " class=divBase>
<span id='" + i + "'>" + msg.d[i].QuestionText + "</span>
<span id='display'" + i + "'>" + answerDisplay +
"<span class='triage'> </span></div>");
msg.d[i].QuestionText is the problem that I'm having. In FF it is displaying the text perfectly. In IE7 the only thing that is displaying is the answerDisplay value which is input elements that I'm writing out on the fly.
When I tak out all the divs and spans and put in some <p></p> then the msg.d[i].QuestionText displays with the answerDisplay value. Can anyone see anything I'm doing incorrectly with this snippet of code?
Thanks!
There's a problem here:
<span id='display'" + i + "'>" + answerDisplay +
That results in:
<span id='display'nn'>text</span>
So that extra quote is bound to cause issues, it should be:
<span id='display" + i + "'>" + answerDisplay +
Also consider adding quotes to the properties on the outer <div>, or constructing the elements as DOM nodes.
You forgot to close a span, you have cases where the quotes don't work out right, and so on.
This is because it's hard to keep track of what's going on in a long string.
This may be more lines, but it's clearer, so you'll make less errors:
// create empty spans and divs
var span1 = $("<span>");
var span2 = $("<span>");
var span3 = ${"<span>");
var div = $("<div>");
// Add html and attributes you need
span1.attr("id", i);
span1.html(msg.d[i].QuestionText);
span2.attr("id", "display" + i);
span2.html(answerDisplay)
span3.attr("class", "triage");
div.attr("id", "qdiv" + i);
div.attr("class", "divbase");
// Add everything to the DOM
div.append(span1);
div.append(span2);
div.append(span3);
$("#QnAList").append(div);
I think using $("</div>") is actually faster, but I used the form above for readability.
Dumb answer for a dumb question :)
I didn't have the ending span tag here:
...<span id='display'" + i + "'>" + answerDisplay +
"<span class='triage'> </span></div>");
Thanks for everyone that looked at it.
Thanks to Nick Craver who helped me debug it.
How do i fix this link in javascript.
Link
Its missing single quotes around 'Business'
Javascript:
html += "<option value='javascript:clientGalleryLink(" + titleArray[x] + ")'>" + titleArray[x] + "</option>";
use \ to escape the quotes
html += "<option value='javascript:clientGalleryLink(\"" + titleArray[x] + "\")'>" + titleArray[x] + "</option>";
<a href='javascript:clientGalleryLink("Business")'>Link</a>
html += "<option value='javascript:clientGalleryLink(\"" + titleArray[x] + "\")'>" + titleArray[x] + "</option>";
Could you please try this one out.
Thanks.
Try this to escape the attribute quotes and thus giving you the single inner quotes like you show in your example.
html += "<option value=\"javascript:clientGalleryLink('" + titleArray[x] + "')\">" + titleArray[x] + "</option>";
Escaping problems like this is why it's best to avoid creating JavaScript-in-HTML dynamically in strings. The javascript: pseudo-URL scheme should also never be used.
Instead, consider an ‘unobtrusive scripting’ approach: move the data out of an embedded JS string and into normal attributes, such as class or, if the link corresponds to a particular element on the page, the href itself:
<a class="gallerylink" href="#Business">Link</a>
for (var i= document.links.length; i-->0;) {
if (document.links[i].className==='gallerylink') {
document.links[i].onclick= function() {
clientGalleryLink(this.hash.substring(1));
return false;
};
}
}
The second example:
html += "<option value='javascript:clientGalleryLink(" + titleArray[x] + ")'>" + titleArray[x] + "</option>";
is just a mess. Aside from the lack of \' quoting around the titleArray value, and the lack of HTML-escaping or JS-string-literal-escaping on the titleArrays (so if you have '"<& characters in the title you've got problems).
Are you expecting the script to get executed when the option is chosen just because you've put it in the value? It won't.
Better to use the DOM objects than trying to mess around inserting JavaScript inside HTML inside JavaScript inside HTML. For example, if you're looking for a select box that calls clientGalleryLink every time the selected option is changed:
<div id="PlaceWhereYouWantToPutTheSelectBox"></div>
<script type="text/javascript">
var s= document.createElement('select');
for (var i= 0; i<titleArray.length; i++) {
s.options[i]= new Option(titleArray[i], titleArray[i]);
}
s.onchange= function() {
clientGalleryLink(this.options[this.selectedIndex].value);
};
document.getElementById('PlaceWhereYouWantToPutTheSelectBox').appendChild(s);
</script>
No ugly escaping necessary, no cross-site-scripting security holes.
add slashes:
\"" + titleArray[x] + "\"