Referencing an array item in a function (as string) javascript - javascript

I created an array of strings, with the format "monthX" where is a number that increases throughout the array.
I have a function where I'm trying to reference a specific item of the array, but it keeps coming in as undefined. Here's my code:
function listCategories() {
categoryList.innerHTML = ""
for (var propertyName in categoryObject) {
var rowHTML = "<div>"
rowHTML += "<span class = 'category'>" + categoryObject[propertyName].name + "</span>"
rowHTML += "<span class = '" + monthList[3] + "'><input/></span>"
rowHTML += "</div>"
categoryList.innerHTML += rowHTML
}
}
//Months to load in
for (var i=0; i<24; i++) {
monthList[i] = "month" + (i + startingMonth)
}
The area I'm interested in is that "monthList[3]" line. That keeps coming in as undefined, even though I console.log(monthList[3]) it correctly says "month6". Any ideas? Do I have bug in my code?

Well, two questions:
WHEN do you call "listCategories()" ?
before or after you set monthList?
And, have you set the global for monthList first?
//globalize monthList array to be usable in functions
var monthList;
function listCategories() {
categoryList.innerHTML = ""
for (var propertyName in categoryObject) {
var rowHTML = "<div>"
rowHTML += "<span class = 'category'>" + categoryObject[propertyName].name + "</span>"
rowHTML += "<span class = '" + monthList[3] + "'><input/></span>"
rowHTML += "</div>"
categoryList.innerHTML += rowHTML
}
}
//Months to load in
for (var i=0; i<24; i++) {
monthList[i] = "month" + (i + startingMonth)
}
//do NOT CALL listCategories prior this line!!
That should do

In the code you show us, you never declare monthList or define it as an array.
function listCategories() {
categoryList.innerHTML = ""
for (var propertyName in categoryObject) {
var rowHTML = "<div>"
rowHTML += "<span class = 'category'>" + categoryObject[propertyName].name + "</span>"
rowHTML += "<span class = '" + monthList[3] + "'><input/></span>"
rowHTML += "</div>"
categoryList.innerHTML += rowHTML
}
}
var monthList = [],
startingMonth = 1;
//Months to load in
for (var i=0; i<24; i++) {
monthList[i] = "month" + (i + startingMonth)
}
Notice the additional lines I added after the function definition, but before the loop.

Related

$.getJSON and for loop with an array and how to get them to work together - for loop completes before JSON is returned

I am trying to cycle through an array and with each value in the array, use $.getJSON to return some JSON and populate an HTML table with the return values.
I have been following this post, but seem not get this to work:
$.getJSON calls misbehaving inside a for loop
Here is my function:
$("#selectProviderTop").click(function() {
var restURL = window.location.protocol + "//" + window.location.hostname + (window.location.port == "" ? "" : (":" + window.location.port)) + "/restGetProvider/";
var selected = [];
var providerKey;
var providerID;
var providerLegacyID;
var providerName;
var finalURL;
var tr;
// First, create an array from the User Provider Keys...
var userProviderKeys = $("#hiddenUserProviderKeys").val();
selected = userProviderKeys.split(",");
console.log("selected: " + selected);
var tableHTML = "";
var focus = $("<div></div>"); // either match an existing element or create one: '<div />'
var arrayLength = selected.length;
for (var i = 0; i < arrayLength; i++) {
(function(i) {
console.log("i: " + i);
providerKey = selected[i];
console.log("providerKey: " + providerKey);
// Get that provider and populate the table...
finalURL = restURL + providerKey;
console.log("finalURL: " + finalURL);
focus.queue('apicalls', function(next) {
$.getJSON(finalURL, function(jsonObject) {
tableHTML += "<tr>";
tableHTML += "<td><a href=\"#\" onclick='selectProvider(\"" + providerKey + "\")'>" + jsonObject["providerName"] + "</a></td>";
tableHTML += "<td>" + jsonObject["providerID"] + "</td>";
tableHTML += "<td>" + jsonObject["providerLegacyID"] + "</td>";
tableHTML += "</tr>";
console.log("tableHTML: " + tableHTML);
next();
});
});
})(i);
}
// Replace table’s tbody html with tableHTML...
console.log("final tableHTML: " + tableHTML);
$("#tableProviderSelect tbody").html(tableHTML);
$('#modalSelectProviderForPTP').modal('show');
});
The userProviderKeys value is 0be32d8057924e718a8b6b4186254756,2dc5f826601e4cc5a9a3424caea4115f
The code never makes the $.getJSON call it just completes the for loop.
How do I update this code to get the first value in the array, grab the JSON, create the HTML, and then cycle through the loop?
I have tried setTimeout but that didn't help me out.
If you have some ideas, could you update my existing code - I understand better when I see the code itself. Thanks.
I don't know why you're doing this using queues. But you are, so I'm not going to rewrite your code to do it some other way.
The last few lines need to be called after all the queued functions have run, which means they should be called asynchronously. (Yes, you could make the whole thing synchronous as Marcus Höglund suggested, but that's no way to write scalable applications in javascript.) You could do this by adding another function to the queue containing these lines. Like this:
$("#selectProviderTop").click(function() {
var restURL = window.location.protocol + "//" + window.location.hostname + (window.location.port == "" ? "" : (":" + window.location.port)) + "/restGetProvider/";
var selected = [];
var providerKey;
var providerID;
var providerLegacyID;
var providerName;
var finalURL;
var tr;
// First, create an array from the User Provider Keys...
var userProviderKeys = $("#hiddenUserProviderKeys").val();
selected = userProviderKeys.split(",");
console.log("selected: " + selected);
var tableHTML = "";
var focus = $("<div></div>"); // either match an existing element or create one: '<div />'
var arrayLength = selected.length;
for (var i = 0; i < arrayLength; i++) {
(function(i) {
console.log("i: " + i);
providerKey = selected[i];
console.log("providerKey: " + providerKey);
// Get that provider and populate the table...
finalURL = restURL + providerKey;
console.log("finalURL: " + finalURL);
focus.queue('apicalls', function(next) {
$.getJSON(finalURL, function(jsonObject) {
tableHTML += "<tr>";
tableHTML += "<td><a href=\"#\" onclick='selectProvider(\"" + providerKey + "\")'>" + jsonObject["providerName"] + "</a></td>";
tableHTML += "<td>" + jsonObject["providerID"] + "</td>";
tableHTML += "<td>" + jsonObject["providerLegacyID"] + "</td>";
tableHTML += "</tr>";
console.log("tableHTML: " + tableHTML);
next();
});
});
})(i);
}
focus.queue('apicalls', function(next) {
// Replace table’s tbody html with tableHTML...
console.log("final tableHTML: " + tableHTML);
$("#tableProviderSelect tbody").html(tableHTML);
$('#modalSelectProviderForPTP').modal('show');
next();
});
});
Edit: Sunshine has pointed out that the linked stackoverflow post has mysterious references to the .dequeue method. In the accepted answer, this method is called explicitly after the tasks have been queued. I don't know whether this was necessary or not. I had thought that the problem was that the $.json bit wasn't happening until after the $("#tableProviderSelect tbody").html(tableHTML); part. But now I realise you wrote: "The code never makes the $.getJSON call it just completes the for loop." In that caseSunshine may have been right, and you need to add focus.dequeue('apicalls'); just after the last focus.queue(...);.

variable being reset in a 'for loop'

I am pushing info from a database to a calendar, where each date has an id equal to an id in the database. The code iterates through the database searching for matching pairs. If a match is found, the name of the image is to be placed into image tags in the calendar. However, the default image is the only one showing, and the variable calImg is seemingly being reset to default. var idCalendar = [];
var arrayCalendar = -1;
var calImg; are global variables
while (counter <= numOfDays) {
var dateID = counter + monthIDName;
idCalendar[counter - 1] = dateID;
//alert(idCalendar[counter-1]);
// When to start new line.
if (weekdays2 > 6) {
weekdays2 = 0;
htmlContent += "</tr><tr>";
}
//check to ensure the mydb object has been created
/////////////////////////////////////////////////////////////////////////////
if (mydb) {
//Get all the entry from the database with a select statement
mydb.transaction(function(t) {
t.executeSql("SELECT rating FROM entry WHERE calendar=?", [idCalendar[arrayCalendar + 1]], function(t, results) {
var i;
//Iterate through the results
if (results.rows.length != 0) {
for (i = 0; i < results.rows.length; i++) {
var row = results.rows.item(i);
calImg = row.rating;
alert(idCalendar[arrayCalendar] + calImg);
}
} else {
alert(idCalendar[arrayCalendar]);
calImg = 'default';
}
});
arrayCalendar++;
});
} else {
myApp.alert("query error");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// if counter is current day.
// highlight current day using the CSS defined in header.
if (counter == day && month == curMonth && year == curYear) {
htmlContent += "<td class='dayNow' id='" + counter + monthIDName + "' onMouseOver='this.style.background=\"#FF0000\"; this.style.color=\"#FFFFFF\"' " + "onMouseOut='this.style.background=\"#FFFFFF\"; this.style.color=\"#FF0000\"'>" + counter + "<img src= 'img/" + calImg + ".png' align='left' height= '15' width= '15'>" + "<br>" + "</td>";
} else {
htmlContent += "<td class='monthNow' id='" + counter + monthIDName + "' onMouseOver='this.style.background=\"#FF0000\"'" + " onMouseOut='this.style.background=\"#FFFFFF\"'>" + counter + "<img src= 'img/" + calImg + ".png' align='left' height= '15' width= '15'>" + "<br>" + "</td>";
}
weekdays2++;
counter++;
}

Javascript for loop variable not working

I am having a problem with my for loop inside a javascript function. The variable i is not working as an argument for the function showAlbum(i). Why is that happening?
var out = "<table>";
for(i = 0; i < arr.length; i++) {
out += "<tr><td><a href=''onclick='showAlbum(i);' >"+
arr[i].artist +
" - " +
arr[i].title +
"</a></td></tr>";
}
out += "</table>";
Because i wrapped in quotations is the literal character i, not the value held within your i variable. You need to evaluate it outside of the quotations:
out += "<tr><td><a href=''onclick='showAlbum(" + i + ");' >"
The i is within the string literal, so variables are not parsed from the string.
Break out of the string like so:
out += "<tr><td><a href=''onclick='showAlbum(" + i + ");' >"+
// ^^^^^^^^^
Try changing the formatting to:
var i,
out = '<table>';
for (i = 0; i < arr.length; i++) {
out += '<tr><td><a href="" onclick="showAlbum(' + i + ')" >' +
arr[i].artist +
' - ' +
arr[i].title +
'</a></td></tr>';
}
out += '</table>';

Not able to display the div content in two container

I want to display the randomly displayed values from 'test1' and 'test2' arrays into two different containers "mainone" and "maintwo". Now I am able to get the random values from array but failed to display the whole html content in containers during on click of click me button each time;
My fiddle here:
https://jsfiddle.net/scrumvisualize/yecoqusp/
Page with data on load
var teama = ["one_1", "one_2", "one_3","one_4", "one_5"];
var test1 = [];
var test2 = [];
function startTeam(){
for(var i = teama.length - 1; i >= 0; i--){
var randomIndex =Math.floor(Math.random()*teama.length);
var rand = teama[randomIndex];
teama.splice(randomIndex, 1);
if(i%2){
test1.push(rand);
}else{
test2.push(rand);
}
}
alert(test1);
alert(test2);
for(var j=0; j<test1.length; j++){
$('#mainone').html('<div id="' + test1[j] + '" class="well">' + test1[j] + '</div>');
}
for(var k=0; k<test2.length; k++){
$('#maintwo').html('<div id="' + test2[k] + '" <div class="well"></div>' + test2[k] + '</div>');
}
}
I tried to work on your fiddle, but no avail, as a guesswork, you have this
for(var j=0; j<test1.length; j++){
$('#mainone').html('<div id="' + test1[j] + '" class="well">' + test1[j] + '</div>');
}
for(var k=0; k<test2.length; k++){
$('#maintwo').html('<div id="' + test2[k] + '" <div class="well"></div>' + test2[k] + '</div>');
}
each loop in the two for-loops is overriding the corresponding div's html,
instead create two variables, say main1html and main2html outside the for loops and the for-loops should be something like:
for(var j=0; j<test1.length; j++){
main1html += '<div id="' + test1[j] + '" class="well">' + test1[j] + '</div>');
}
for(var k=0; k<test2.length; k++){
main2html += '<div id="' + test2[k] + '" <div class="well"></div>' + test2[k] + '</div>';
}
and after the two for-loops assign the final html to both divs, like this:
$('#mainone').html(main1html);
$('#maintwo').html(main2html);
Ok, so, as was mentioned elsewhere, using .html() is just overriding the data each time. There are a couple issues in your code, however.
You are not properly closing your div(s) in the second loop.
You need to append the new data to the container (clear the container first if you need to, I do in my example.)
Fiddle
var teama = ["one_1", "one_2", "one_3","one_4", "one_5"];
var test1 = [];
var test2 = [];
function startTeam(){
for(var i = teama.length - 1; i >= 0; i--){
var randomIndex =Math.floor(Math.random()*teama.length);
var rand = teama[randomIndex];
teama.splice(randomIndex, 1);
if(i%2){
test1.push(rand);
}else{
test2.push(rand);
}
}
alert(test1);
alert(test2);
// i'm emptying the containers, you may not need to depending
// on your implementation
$('#mainone').empty();
$('#maintwo').empty();
for(var j=0; j < test1.length; j++){
// use append here, not html
$('#mainone').append('<div id="' + test1[j] + '" class="well">' + test1[j] + '</div>');
}
for(var k=0; k<test2.length; k++){
// use append here, not html
// i also fix your markup ( you were not closing the div properly)
$('#maintwo').append('<div id="' + test2[k] + '" class="well">' + test2[k] + '</div>');
}
}

dynamic drop down list values javascript

I want to populate my drop down list with dynamic values but the list remains empty in other words no option is shown Could someone help me !!!
here is my code http://jsfiddle.net/n6ahz/24/
var newdiv = document.createElement('div');
var text="TEXT";
var n=0;
newdiv.innerHTML += "<br> Question " + (n) + " : " + text + " ? <br><br>";
var m = 0;
var options = '';
for (var j = 1; j < 5; j++) {
var val = "marwa" + j;
if (val) {
m++;
options += " <option value="+j+"> " + val + "</option>";
}
}
newdiv.innerHTML += "<select name='single' id='single'>";
newdiv.innerHTML += " "+options + " </select> ";
document.getElementById('results').appendChild(newdiv);​
Instead of
newdiv.innerHTML += "<select name='single' id='single'>";
newdiv.innerHTML += " "+options + " </select> ";
try
newdiv.innerHTML += "<select name='single' id='single'> "+options + " </select> ";
I don't think adding HTML a bit at a time works because the browser will try to render it immediately.
With innerHTML, the actual DOM gets updated everytime you make a change. So you can't reliably make piecemeal changes like you're doing. Create a variable like var html and save all your HTML updates into it, then set element.innerHTML = html.
var newdiv = document.createElement('div');
var html = "";
var text="TEXT";
var n=0;
html += "<br> Question " + (n) + " : " + text + " ? <br><br>";
var m = 0;
var options = '';
for (var j = 1; j < 5; j++) {
var val = "marwa" + j;
if (val) {
m++;
options += " <option value="+j+"> " + val + "</option>";
}
}
html += "<select name='single' id='single'>";
html += " "+options + " </select> ";
newdiv.innerHTML = html;
document.getElementById('results').appendChild(newdiv);​
var newdiv = document.createElement('div');
var text="TEXT";
var n=1;
newdiv.innerHTML += "<br> Question " + (n) + " : " + text + " ? <br><br>";
var m = 1;
var options = '';
for (var j = 0; j <= 5; j++) {
var val = "marwa" + j;
if (val) {
m++;
options += " <option value="+j+"> " + val + "</option>";
}
}
newdiv.innerHTML += "<select name='single' id='single' "+options + " </select> ";
document.getElementById('results').appendChild(newdiv);​

Categories