Javascript - passing parameter to function which calls another function - javascript

Okay my title is a bit confusing but basically, I have a function and after that function is finished executing, it should do the given steps. Here is my javascript:
createSideTable(showThis, function() {
$('#' + showThis + 'Screen').slideDown('slow');
});
I want the createSideTable function to run all it's code before the step
$('#' + showThis + 'Screen').slideDown('slow');
can get executed. The createSideTable more or less just makes a side table fade in slowly. The function can be seen at the end of this post.
Normally, when I have a function which I want to execute all it steps and then execute other given steps, i'd do it like this
createSideTable(function() {
$('#' + showThis + 'Screen').slideDown('slow');
});
and it works, however, the createSideTable function needs a parameter (the parameter which it needs is showThis). So when I tried
createSideTable(showThis, function() {
$('#' + showThis + 'Screen').slideDown('slow');
});
it did create the sideTable however, this step
$('#' + showThis + 'Screen').slideDown('slow');
didn't get executed after it created the sideTable. How come?
This is my createSideTable function.
function createSideTable(test) {
var key = test.substr(test.length -1); //index of Heading
for (var i=0; i<window['headings' + key].length; i++) {
if (i == 0) {
$('#row' + i).addClass('subHeadingClicked');
}
$('#row' + i).text('').removeClass('column1invisible');
$('#row' + i).append(window['headings' + key][i]);
}
$('#sideTable').fadeIn(1500);
}

Add the callback parameter, and if it exists, call it at the end:
function createSideTable(test, callback) {
var key = test.substr(test.length -1); //index of Heading
for (var i=0; i<window['headings' + key].length; i++) {
if (i == 0) {
$('#row' + i).addClass('subHeadingClicked');
}
$('#row' + i).text('').removeClass('column1invisible');
$('#row' + i).append(window['headings' + key][i]);
}
$('#sideTable').fadeIn(1500);
if (callback) callback();
}
And you should be able to call it like this:
createSideTable(showThis, function() {
$('#' + showThis + 'Screen').slideDown('slow');
});
Edit -
The first example was showing how a callback works. You can execute the callback where ever you want... for example, if you want it to be executed after the fadeIn(), you could do this:
function createSideTable(test, callback) {
var key = test.substr(test.length -1); //index of Heading
for (var i=0; i<window['headings' + key].length; i++) {
if (i == 0) {
$('#row' + i).addClass('subHeadingClicked');
}
$('#row' + i).text('').removeClass('column1invisible');
$('#row' + i).append(window['headings' + key][i]);
}
$('#sideTable').fadeIn(1500, function() {
if (callback) callback();
});
}

Related

Increment id value in jQuery selector

I have the following code:
$("#cc").on('hidden.bs.modal', function (e) {
$("#cc iframe").attr("src", $("#cc iframe").attr("src"));
});
I would like to apply that to 10 different divs in my markup (#cc-1, #cc-2, #cc-3, etc...).
I tried using a for loop so I don't have to rewrite the same code 10 times by doing the following:
for (var i = 1; i < 11; i++) {
$('"#cc-' + i + ' iframe"').on('hidden.bs.modal', function (e) {
$('"#cc-' + i + ' iframe"').attr("src", $('"#cc-' + i + 'iframe"').attr("src"));
});
}
The thing is, I don't know how to concatenate the variable i inside my jQuery selector with everything else.
Please note that I need to target the iframe inside every #cc- div. This is the part what I'm getting trouble with. When adding the iframe after the concatenation of the #cc- with the variable i I get a syntax error.
I hope I made myself clear. Any clues in what I'm doing wrong?
You should be able to concatenate a variable in a selector like you are doing, however you don't need to add quotations.
Change this:
$('"#cc-' + i + ' iframe"')
To this:
$('#cc-' + i + ' iframe')
Also you are forgetting to add a space infront of your iframe class.
Change this:
$('"#cc-' + i + 'iframe"')
To This:
$('#cc-' + i + ' iframe')
Complete Change:
for (var i = 1; i < 11; i++) {
$('#cc-' + i + ' iframe').on('hidden.bs.modal', function (e) {
$('#cc-' + i + ' iframe').attr("src", $('#cc-' + i + ' iframe').attr("src"));
});
}
for (var i = 1; i < 11; i++) {
var mydiv="#cc-"+i;
$("mydiv iframe").on('hidden.bs.modal', function (e) {
$('"#cc-' + i + ' iframe"').attr("src", $('"#cc-' + i + 'iframe"').attr("src"));
});
}

Iterating through array in getJSON callback

I am trying to invoke a getJSON function for each value in an array and if the user is offline, display their name. However, I keep getting undefined. When a number is hard coded for i though, it works fine.
function getStreamersList() {
$('#listOfStreams').html("");
for (var i = 0; i < streamers.length; i++) {
console.log("This works: " + streamers[i]);
$.getJSON('https://api.twitch.tv/kraken/streams/' + streamers[i], function(data) {
if (data.stream !== null) {
$('#onlineStreams').append('<div class="online"><p>' + data.stream.channel.status + '</p></div>');
} else {
console.log(streamers[i]);
$('#offlineStreams').append('<div class="offline"><p>' + streamers[i] + ' is offline.</p></div>');
}
}, 'jsonp')
}
}
Can someone please explain what's happening? Thanks for any help!

Understanding variable mistakes within closures?

I am learning about closures. This example is given as a common mistake made when making a closure:
function assignTorpedo(name, passengerArray) {
var torpedoAssignment;
for (var i = 0; i<passengerArray.length; i++) {
if (passengerArray[i] == name) {
torpedoAssignment = function() {
alert("Ahoy, " + name + "!\n" +
"Man your post at Torpedo #" + (i+1) + "!");
};
}
}
return torpedoAssignment;
}
Since the for loop completes before the closure is returned, the i value will not match with the name. So, I understand that the loop continues on before the return happens.
My question comes from this, an example of the correct way to do things:
function makeTorpedoAssigner(passengerArray) {
return function (name) {
for (var i = 0; i<passengerArray.length; i++) {
if (passengerArray[i] == name) {
alert("Ahoy, " + name + "!\n" +
"Man your post at Torpedo #" + (i+1) + "!");
}
}
};
}
I don't understand why in the above example the for loop wouldn't also continue past the first time it finds a match, which would result in another mismatched i. I understand that return stops a function, but I don't understand the connection between the return and that first match since they don't happen together (visually). I understand how the code knew to stop if that return was within the if function or the for loop.
I don't understand why in the above example the for loop wouldn't also continue past the first time it finds a match
It would.
which would result in another mismatched i.
It wouldn’t, because it checks if (passengerArray[i] == name) every time. That’s wasteful, though; it’s an unusual fix. A better way would be to pass the index:
function makeTorpedoAssigner(passengerArray, i) {
return function (name) {
alert("Ahoy, " + name + "!\n" +
"Man your post at Torpedo #" + (i+1) + "!");
};
}
function assignTorpedo(name, passengerArray) {
for (var i = 0; i<passengerArray.length; i++) {
if (passengerArray[i] == name) {
return makeTorpedoAssigner(passengerArray, i);
}
}
}
What happens here is :
assignTorpedo() returns a function based on name, So, every time it
checks for name in passengerArray and returns a function, but before
assignTorpedo could return torpedoAssignment, value of i would have
changed to the last value (length-1 of passengerArray), as loop will continue executing.
function assignTorpedo(name, passengerArray) {
var torpedoAssignment;
for (var i = 0; i<passengerArray.length; i++) {
if (passengerArray[i] == name) {
torpedoAssignment = function() {
alert("Ahoy, " + name + "!\n" +
"Man your post at Torpedo #" + (i+1) + "!");
// value of i
};
}
}
// value of i = length of Array since loop has executed fully
return torpedoAssignment;
}
Right approach explained :
Here you are returning a function which takes a name and checks each
time in the array, the concept of closure here is that, even though
function(name) is returned, it would remember passengerArray (if you
will see passengerArray is not passed everytime, but no error is
thrown. This is closure.)
function makeTorpedoAssigner(passengerArray) {
return function (name) {
for (var i = 0; i<passengerArray.length; i++) {
if (passengerArray[i] == name) {
alert("Ahoy, " + name + "!\n" +
"Man your post at Torpedo #" + (i+1) + "!");
//value of i
}
}
};
}

json call does'nt update in IE 10

I use this tiny script to feed a playlist and updates it every 20 sec. - for some reason it does'nt update in ie10 (and older versions too, I guess) - I failed to see where it goes wrong, any ideas...?
function playlist() {
$.getJSON("/playlist/", function (data) {
$("#play-now-arti").empty();
$("#play-now-title").empty();
$("#last-played").empty();
var i = 0;
$.each(data.PlayHistory.PlayInfo, function (index, value) {
var arti = value["ARTI"];
var title = value["TITLE"];
i++;
if (i == 1) {
$("#now-playing-artist").html(arti);
$("#now-playing-song").html(title);
}
else if (i > 1 && i < 8) {
$("<li>" + arti + " - <span>" + title + "</span></li>").appendTo("#last-played");
}
});
});
setTimeout(playlist, 20000);
};
playlist();
It was caching, indeed... - by adding "$.ajaxSetup({ cache: false });" to my function IE now updates just like the other browsers...
function playlist() {
$.ajaxSetup({ cache: false });
$.getJSON("/playlist/", function (data) {
$("#playlist").empty();
var i = 0;
$.each(data.PlayHistory.PlayInfo, function (index, value) {
var arti = value["ARTI"];
var title = value["TITLE"];
var spotify = value["Spotify"];
i++;
if (i == 1) {
$("<li class=\"jp-playlist-current\"><div tabindex=\"0\" class=\"jp-playlist-item jp-playlist-current\"><span class=\"jp-artist\">" + arti + ":</span><img src=\"/img/spotify.png\" style=\"border: 0;\" /><br><span class=\"jp-title\">" + title + "</span></div></li>").appendTo("#playlist");
}
else {
$("<li><div tabindex=\"0\" class=\"jp-playlist-item\"><span class=\"jp-artist\">" + arti + ":</span><img src=\"/img/spotify.png\" style=\"border: 0;\" /><br><span class=\"jp-title\">" + title + "</span></div></li>").appendTo("#playlist");
}
});
});
setTimeout(playlist, 200000);
};
playlist();

Need some help synch'ing outer loop counter with dialog.onconfirm()

I am writing a game for Facebook. IN the following code, I have a problem. I have a for loop executing, and in that loop, I call a dialog and implement 'onconfirm' for the dialog. The problem is that I need to access th e loop counter inside of the onconfirm function. But because the onconfirm is called outside of the scope of the for loop, the counter value is no longer valid because it's been incremented. I need some way to pass the counter value to the dialog onconfirm as it was at the time the dialog was displayed, not after the loop has finished. Or maybe someone has a better solution. Any help would be appreciated. Thanks.
function unloadCargo() {
//debugger;
var actionPrompt = document.getElementById('action-prompt');
actionPrompt.setTextValue('Unloading cargo...');
var ajax = new Ajax();
ajax.responseType = Ajax.JSON;
ajax.ondone = function(data) {
debugger;
if(data.unloadableCargo.length == 0) {
loadCargo();
} else {
//console.log('unloadable cargo='+dump(data.unloadableCargo));
var i = 0;
var j = 0;
var ucCount = data.unloadableCargo.length;
for(i = 0; i < ucCount; i++) {
cargoDialog = new Dialog();
cargoDialog.showChoice('Unload Cargo', 'Unload ' + data.unloadableCargo[i].goods_name + ' at ' + data.unloadableCargo[i].city_name + ' for ' + data.unloadableCargo[i].payoff + 'M euros?');
cargoDialog.onconfirm = function() {
//console.log('unloadable cargo onconfirm='+dump(data.unloadableCargo));
var ajax = new Ajax();
var param = {"city_id": data.unloadableCargo[i].city_id, "goods_id": data.unloadableCargo[i].goods_id, "payoff": data.unloadableCargo[i].payoff};
ajax.ondone = function(demandData) {
var demands = document.getElementById('demands');
var innerXhtml = '<span>';
for(var j = 0; j < demandData.demands.length; j++) {
innerXhtml = innerXhtml + ' <div class="demand-item"><div class="demand-city">' + demandData.demands[j].city + '</div><div class="demand-pay">' + demandData.demands[j].cost + '</div><div class="demand-goods">' + demandData.demands[j].goods + '</div></div>';
}
innerXtml = innerXhtml + ' </span>';
demands.setInnerXHTML(innerXhtml);
// update balance
loadCargo();
}
ajax.post(baseURL + "/turn/do-unload-cargo", param);
}
cargoDialog.oncancel = function() { loadCargo(); }
}
//loadCargo();
}
}
ajax.post(baseURL + '/turn/unload-cargo');
}
You need to pass the value to the dialog somehow.
I have never looked at the FBJS, but it seems setContext can be used for that.
Try this:
cargoDialog = new Dialog().setContext({currentIndex: i});
// showChoice is the same
cargoDialog.onconfirm = function() {
alert(this.currentIndex); // Here you should be able to get it
}

Categories

Resources