JQuery Closure dynamic controls - javascript

I'm having some confusion with closures
<script type="text/javascript">
$(function () {
for (var i = 0; i < 7; i++) {
var cname = '#closingTimePicker' + i;
$(cname).datetimepicker({
format: 'LT'
});
var oname = '#openingTimePicker' + i;
$(oname).datetimepicker({
format: 'LT'
});
$(oname).on("dp.change", function (e) {
$(cname).data("DateTimePicker").minDate(e.date);
});
$(cname).on("dp.change", function (e) {
$(oname).data("DateTimePicker").maxDate(e.date);
//Loop issue here
});
}
});
</script>
>
In the above script i'm confused how to apply closure so that i cloud get the correct date picker based on the loop. any suggestions and importantly explanation would be a great help.
Thanks,

every loop cname and oname gets a new value. so when dp.change on a oname object is triggered, cname has always the last value it gets in the loop.
try something like this:
<script type="text/javascript">
function initPicker(cname, oname)
{
// paste here the rest of the loop
}
for (var i = 0; i < 7; i++) {
var cname = '#closingTimePicker' + i;
var oname = '#openingTimePicker' + i;
initPicker(cname, oname);
}
</script>
[EDIT]
short explanation:
scopes live as long as their variables. so "scope" initPicker is 7 times initialized with different filled variables.
[/EDIT]
enjoy (-:

Related

A javascript function that complete another function sent as a parameter?

In the following javascript function window.setInterval(function,milliseconds) I can do the following:
var myvarible = function(){alert('Popup');};
window.setInterval(myvarible,5000);
now every 5 seconds my webpage will alert the message 'popup'
How can I make my own function do the parameter myvarible, as see above? This is what I am trying below, but it does not work.
text = "";
var myvarible = function() {
for (i = 0; i < cars.length; i++) {
text += cars[i] + "<br>";
}
}
function howLong(the_function){
var starting_time = new Date().getMilliseconds();
the_function //do the function here
var finishing_time = new Date().getMilliseconds();
var difference = finishing_time-starting_time;
document.write(difference);
}
howLong(myVarible); //call my howLong function
I hope you understand me, I have tried to make myself as clear as possible and I am new to javascript so please try to keep the answers as simple as possible.
Thanks for your help
Put () after the variable to call it as a function:
the_function(); // do the function here
You have to make 3 corrections.
1.) calling howLong(myVarible); should be howLong(myvarible); because you are defining function as myvarible
2.)You have to call the function add () in function howLong
`the_function() //do the function here`
3.) define cars.
This worked for me
<script>
text = "";
var cars = [1,2,3];
var myVarible = function() {
for (i = 0; i < cars.length; i++) {
text += cars[i] + "<br>";
}
}
function howLong(the_function){
var starting_time = new Date().getMilliseconds();
the_function() //do the function here
var finishing_time = new Date().getMilliseconds();
var difference = finishing_time-starting_time;
document.write(difference);
}
howLong(myVarible); //call my howLong function
</script>

How can I make this function loop with javascript?

function argsToArray(args) {
var r = []; for (var i = 0; i < args.length; i++)
r.push(args[i]);
return r;
}
argsToArray(document.getElementsByTagName('img')).forEach(function(img) {
img.src = img.src.split('VTlibOlte8YCb').join('X0X810D0' + Math.floor((Math.random()*10)+1));;
});
I tried adding setInterval(argsToArray,500); at the end but that seem to have broken things.
This is quite archaic and will probably crash the browser, but for this experiment it might just work.
function reloadPage()
{
location.reload();
}
setInterval(reloadPage,.5);
I assume from using native forEach that you're targeting IE9+, so instead of manually pushing the collection contents into an array you could just:
function argsToArray(args) {
return Array.prototype.slice.call(args)
}
The rest of the code looks perfectly workable, maybe there's something wrong with the split() or join() arguments. Please explain what are you trying to achieve here.
Adding setInterval(argsToArray,500) would just call your first function without any arguments, you should use an anonymous function or pass arguments into the setInterval/setTimeout function (see MDN).
So you want to do something like this?
window.onload=function() {
var imgs = document.images;
var tId = setInterval(function() {
for (var i=0;i<imgs.length;i++) {
var img = imgs[i];
var val = 'X0X810D0' + (Math.floor(Math.random()*10)+1);
img.src = img.src.replace(/VTlibOlte8YCb/g,val);
}
},1000);
}
which is designed replace the src of each image every second - but actually only once since there is no more VTlibOlte8YCb to replace after the first time
Here is one that does replace the value each time
Live Demo
window.onload=function() {
var imgs = document.images;
var oldVal = new RegExp(/VTlibOlte8YCb/g);
var val = 'X0X810D0' + (Math.floor(Math.random()*10)+1);
var tId = setInterval(function() {
for (var i=0;i<imgs.length;i++) {
var img = imgs[i];
val = 'X0X810D0' + (Math.floor(Math.random()*10)+1);
img.src = img.src.replace(oldVal,val);
oldVal = new RegExp("/"+val+"/g");
}
},200);
}

Javascript array results returning undefined

I have been working on a simple math game and am having problems getting the overall answer results to return after the end of the game.
Here is what my return function looks like
function pShowResults() {
var pNumResults = document.getElementById("results");
for (var i = 0; i <= 10; i++) {
pNumStore.push(pNumGuess[i]);
var pNumTable = document.createElement("div");
pNumTable.innerHTML = (pNumGuess[i]);
pNumResults.appendChild(pNumTable);
}
}
Here is the full script
Pretty much need debugging help. I new to this so I'm guessing there is a ton that's off, but as long as I can get the results fed back I should be fine.
You are not passing the value of x in many placess
$(document).ready(function () {
//declare arrays and variables for use below
var pNum1 = [];
var pNum2 = [];
var pNumAns = [];
var pNumGuess = [];
var pNumStore = [];
var pNumCarry = 0;
var pNumTrack = 0;
var pNumMessageRight = ['Awesome Job!', 'Correct!', 'Great Job!'];
var pNumMessageWrong = ['Oh No! That Was Wrong!', 'Incorrect!', 'That\'s Wrong'];
$(".Play").click(function () {
$("#popup").attr("class", "on");
pNumTrack = 0;
pNumGen(pNumTrack);
});
$(".pNumSubmit").click(function () {
pNumCalc(pNumTrack-1);
});
$(".pNumNext").click(function () {
pNumGen(pNumTrack);
});
function pNumGen(x) {
pNum1[x] = (Math.round(Math.random() * 51));
pNum2[x] = (Math.round(Math.random() * 51));
pNumAns[x] = pNum1[x] + pNum2[x];
$(".pNum1").html(pNum1[x]);
$(".pNum2").html(pNum2[x]);
$(".pNumGuess").val("");
$(".pNum1").html(pNumTrack[x]);
if (pNumTrack == 2) {
$(".pNumNext").html("");
$(".pNumSubmit").html("Close");
pShowResults();
}
pNumTrack++;
}
function pNumCalc(x) {
pNumGuess[x] = $(".pNumGuess").val();
if (pNumGuess[x] == pNumAns[x]) {
$(".message").html(pNumMessageRight[Math.floor(Math.random() * pNumMessageRight.length)]);
$(".pNumNext").html("Next Question >")
} else {
$(".message").html(pNumMessageWrong[Math.floor(Math.random() * pNumMessageWrong.length)]);
$(".pNumNext").html("Maybe The Next Question >")
}
}
function pShowResults() {
var pNumResults = document.getElementById("results");
for (var i = 0; i < pNumGuess.length; i++) {
pNumStore.push(pNumGuess[i]);
var pNumTable = document.createElement("div");
pNumTable.innerHTML = (pNumGuess[i]);
pNumResults.appendChild(pNumTable);
}
}
});
Demo: Fiddle
There is a function called pNumCalc in your code which you have set to take in an argument, but you never pass one in. You use the argument to store the results in the pNumGuess array, but since the argument is never passed in, the guesses are never stored, and you end up with undefined as the answers the user gave.
Updated fiddle: http://jsfiddle.net/dwdX9/2/. Not sure how close this is to what you actually want though, but hopefully it gets you on the right track.
Because StackOverflow wants code to to be included when JSFiddle is...:
pNumCalc(pNumTrack)
You forget to define array before use it.
function pShowResults() {
var pNumStore = new Array();
var pNumResults = document.getElementById("results");
for (var i = 0; i <= 10; i++) {
pNumStore.push(pNumGuess[i]);
var pNumTable = document.createElement("div");
pNumTable.innerHTML = (pNumGuess[i]);
pNumResults.appendChild(pNumTable);
}
}
I must suggest you should use jquery instead.
After visiting your Fiddle seems like there are many problems with the code. and also your question is unclear.
for e.g.
$(".pNumSubmit").click(function () {
//why x value not passed?
pNumCalc();
});
function pNumCalc(x) {
pNumGuess[x] = $(".pNumGuess").val();
if (pNumGuess[x] == pNumAns[x]) {
$(".message").html(pNumMessageRight[Math.floor(Math.random() * pNumMessageRight.length)]);
$(".pNumNext").html("Next Question >")
} else {
$(".message").html(pNumMessageWrong[Math.floor(Math.random() * pNumMessageWrong.length)]);
$(".pNumNext").html("Maybe The Next Question >")
}
}
Please clear which array is returning undefined so that others can help you.

no wrap (head) vs onLoad

In this demo, i got different outputs, if i use (no wrap) or (onLoad).
My question is, in html file, to get a correct alert: 1,2,3,4 what alteration is needed in code ? With a simple load of dojo i got always 4 in all alerts:
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojo/dojo.xd.js"></script>
<script type="text/javascript">
var slider = [];
for (i = 0; i < 4; i++) {
slider[i] = function () {
alert([i]);
};
dojo.addOnLoad(slider[i]);
}
</script>
You could use a closure:
var slider = [];
for (i = 1; i < 5; i++) {
slider[i] = (function (i) {
return function () { alert([i]); }
})(i);
dojo.addOnLoad(slider[i]);
}
This will save i into another functions scope saving the state. Without the closure, i is scoped to the original function.
The value of i is 4 at the end of the loop, which is what your functions will see when they are called. Something like this should work:
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojo/dojo.xd.js"></script>
<script type="text/javascript">
var slider = [];
for (i = 0; i < 4; i++) {
eval("slider[i] = function () { alert([" + i + "]);};");
dojo.addOnLoad(slider[i]);
}
</script>
Edit: well you could also try doing the counting when the functions are called rather than when they're defined. e.g.
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojo/dojo.xd.js"></script>
<script type="text/javascript">
var slider = [];
var onLoadCounter = 0;
var onLoadCallback = function() {
alert(onLoadCounter);
onLoadCounter++;
};
for (i = 0; i < 4; i++) {
slider[i] = onLoadCallback;
dojo.addOnLoad(slider[i]);
}
</script>

Dynamic dropdown options not showing in IE7

We have a dropdown list that is dynamically populated using javascript (below). But it doesn't show in IE7.
This is the code that populates the options:
<script language="javascript" type="text/javascript">
window.onload = function() {
var today= new Date();
var year= today.getFullYear();
var val =0;
t2= 51;
grad_yr = document.getElementById("grad_yr");
grad_yr.options[0] = new Option("Year",val,false,false);
var y=year;
var yy=y;
for (var i=1; i <t2 ; i++) {
grad_yr.options[i] = new Option(y,y);
y=yy-1;
yy--;
}
}
</script>
This is the HTML:
<select name="grad_yr" id="grad_yr"></select>
What could be wrong?
EDIT: Ok, nevermind. Apparently, the list is actually being populated. It's just that we have another javascript that sort of moves the position of the options that's why it looks hidden. Thanks anyway!
You've created a name collision by using the same global variable name for your grad_yr variable and the select element. Comment out the line where you are pulling your grad_yr from the document by ID, as it is unneccessary:
//grad_yr = document.getElementById("grad_yr");
grad_yr.options[0] = new Option("Year", val, false, false);
Or, if you really do need to have a variable reference, just give your variable a different name, like this (or some such):
grad_yrVar = document.getElementById("grad_yr");
grad_yrVar.options[0] = new Option("Year", val, false, false);
...
for (var i = 1; i < t2; i++) {
grad_yrVar.options[i] = new Option(y, y);
y = yy - 1;
yy--;
}
...and it should work.
Try this
var grad_yr = document.getElementById("grad_yr");

Categories