Add elements in a while loop JavaScript - javascript

I'm trying to make a while loop that contains two if statements and I don't want to increment until those are done. How would I go by to solve this issue, now the page freezes when I implement the while loop.
var task = 0;
while(task < 3) {
//Enter the title and url and add it to site
if(window.location.href.indexOf("website.com") > -1) {
$("input[name=Title]").val(GM_getValue("title" + task));
$("input[name=SvURL-1]").val(GM_getValue("url" + task));
$( 'button[name=submit]' ).click();
}
//Enters the imdbid to the stream
if(window.location.href.indexOf("anotherwebsite.com") > -1) {
console.log($("input[name=EmbedID]").val());
console.log(GM_getValue("imdid" + task));
if ($("input[name=EmbedID]").val() != GM_getValue("imdid" + task)) {
$( "a[data-target=#EditURL]" ).click();
$("input[name=EmbedID]").attr("value", GM_getValue("imdid" + task));
setTimeout(function(){
$( 'button:contains("Ok")' ).click();
}, 1000);
setTimeout(function(){
$( 'button[name=submit]' ).click();
}, 1000);
} else {
setTimeout(function(){
window.location.replace("https://website.com");
}, 1000);
task++;
alert("task when done: " + task);
}
}
}

I would rather suggest to go with a method & call the method.
Something like this
var task = 0;
var taskMethod = function(){
//Enter the title and url and add it to site
if(window.location.href.indexOf("website.com") > -1) {
$("input[name=Title]").val(GM_getValue("title" + task));
$("input[name=SvURL-1]").val(GM_getValue("url" + task));
$( 'button[name=submit]' ).click();
}
//Enters the imdbid to the stream
if(window.location.href.indexOf("anotherwebsite.com") > -1) {
console.log($("input[name=EmbedID]").val());
console.log(GM_getValue("imdid" + task));
if ($("input[name=EmbedID]").val() != GM_getValue("imdid" + task)) {
$( "a[data-target=#EditURL]" ).click();
$("input[name=EmbedID]").attr("value", GM_getValue("imdid" + task));
setTimeout(function(){ $( 'button:contains("Ok")' ).click();}, 1000);
setTimeout(function(){ $( 'button[name=submit]' ).click();}, 1000);
} else {
setTimeout(function(){ window.location.replace("https://website.com");}, 1000);
task++;
console.log("task when done: " + task);
if(task < 3)
taskMethod();
}
}
}
//Initial (First Time) method call
taskMethod();
Hope this will help you.

I can see that you're only incrementing the variable task when a certain condition is met. But since you're inside a while loop, if none of the conditions are met for the variable task to increment, then the while loop will not exit. Thus explains the freezing of the page.
What you can do is something like this:
var flag = false;
var task = 0;
while (task < 3) {
if (condition) {
// some code here...
}
if (condition) {
if (condition) {
// some code here...
} else {
// some code here...
flag = true;
}
}
task++;
}
if (flag) {
// do something here...
}

Related

JavaScript clearTimeout not firing correctly

I have a submit function on a textbox with JavaScript. When the script fires, it checks a Kendo grid for a certain article and adds +1 to its quantity as well as opening the corresponding cell in editing mode. What I want to achieve is that on every submit the timer that starts grid.editCell() will reset its timer.
Currently, the event fires properly. However, the timer doesn't get reset, although the clearTimeout() does work if I just simply start the timer and then clear it right afterwards.
JavaScript:
$('#txtBarcode').submit(function (e) {
var grid = $("#PickListDetailGrid").data("kendoGrid");
var dataSource = $("#PickListDetailGrid").data("kendoGrid").dataSource;
var allData = grid.dataSource.data();
var code = this.value;
var notification = $("#notification").data("kendoNotification");
var timer = null;
clearTimeout(timer);
$.each(allData, function (index, item) {
if (item.ArticleID == code) {
clearTimeout(timer);
timer = null;
if (item.Quantity > item.PickedQuantity && item.PickedQuantity.toString().length < 4) {
var edit = function () {
if (item.PickedQuantity != item.Quantity && timer != null) {
grid.select("tr:eq(" + (index) + ")");
grid.editCell("tr:eq(" + (index + 1) + ") td:eq(" + (5) + ")");
} else {
//do nothing
}
}
item.PickedQuantity++;
item.dirty = true;
dataSource.sync();
if (item.PickedQuantity != item.Quantity) {
console.log("tik tok");
if (timer) {
clearTimeout(timer); //cancel the previous timer.
timer = null;
}
timer = setTimeout(edit, 3000);
} else {
clearTimeout(timer);
timer = null;
}
document.getElementById("txtBarcode").value = "";
} else {
if (item.PickedQuantity.toString().length > 4) {
notification.hide();
notification.show({
message: "Added item"
}, "upload-success");
} else {
notification.hide();
notification.show({
title: "Quantity Error",
message: "You already picked this item to the maximum"
}, "error");
document.getElementById("txtBarcode").value = "";
grid.select("tr:eq(" + (index) + ")");
grid.editCell("tr:eq(" + (index + 1) + ") td:eq(" + (5) + ")");
$('.focus :input').focus();
}
}
}
})
})
You can try delay function like this. The delay function should be outside of the each function.
var delay = (function() {
var timer = 0;
return function(callback, ms) {
clearTimeout(timer);
timer = setTimeout(callback, ms);
};
})();
delay(function() {
//do something
}, 3000);
The problem was that var timer = null; had to be outside of the submit function to be properly cleared and set to null before assigning a new setTimeout() to it.

How to make a button disable automatically?

I'm trying to code a button - each time you click it, it disables for 3 seconds...but for some reason, it waits a second then disables it. How would you make it so that it disables automatically? This is some of my code so far:
function countdown() {
setTimeout(function () {
document.getElementById('btnOne').disabled = null;
}, 4000);
var countdownNum = 4
incTimer();
function incTimer() {
setTimeout(function () {
if (countdownNum != 1) {
countdownNum--;
document.getElementById('timeLeft').innerHTML = 'Click again in ' + countdownNum;
incTimer();
document.getElementById('btnOne').disabled = true;
} else {
document.getElementById('timeLeft').innerHTML = '';
document.getElementById('btnOne').disabled = false;
}
}, 1000);
}
}
This works for me
<span id="timeLeft"></span>
<input type="submit" id="btnOne" onClick="countdown()">
function countdown() {
document.getElementById('btnOne').disabled = true;
var countdownNum = 3
document.getElementById('timeLeft').innerHTML = 'Click again in ' + countdownNum;
incTimer();
function incTimer() {
setTimeout(function () {
if (countdownNum != 1) {
countdownNum--;
document.getElementById('timeLeft').innerHTML = 'Click again in ' + countdownNum;
incTimer();
document.getElementById('btnOne').disabled = true;
} else {
document.getElementById('timeLeft').innerHTML = '';
document.getElementById('btnOne').disabled = false;
}
}, 1000);
}
}
I believe this code does the things you need.
<script type="text/javascript">
function fclick(){
document.getElementById('myButton').disabled = true;
setTimeout('countDown(3);', 1000);
}
function countDown(i){
if (i >= 0)
{
document.getElementById('myButton').value = 'Click again in ' + i + ' secs';
i--;
setTimeout('countDown('+i+');', 1000);
}
else
{
document.getElementById('myButton').value = 'Click me';
document.getElementById('myButton').disabled = false;
}
}
</script>
<input type="button" value="Click me" id="myButton" onclick="fclick()">
You are setting a timeout that says "after 1 second, do X".
Your current timeout is actually pretty hard to follow, but it broadly does this in a very tangled way:
Make counter = 4
Wait 1 second.
If counter != 1, subtract 1 from the counter, disable button, and go back to 2. Continue otherwise.
Enable button.
As you can see, you are disabling the button AFTER waiting 1 second, not immediately.
I would suggest changing your countdown() method as follows:
Disable button.
Make counter = 3
If counter > 0, Print "Click again in counter seconds", Subtract 1 from counter, Wait 1 second and go back to 2. Continue Otherwise.
Enable button.
That could look like this: (using your code)
--- Working Example Here!!! ---
function countdown() {
document.getElementById('btnOne').disabled = true;
//3 is more understandable than 4 for your example.
var countdownNum = 3;
incTimer();
function incTimer() {
if (countdownNum > 0) {
// Order of statements IS important.
// Note the differences in this IF block.
document.getElementById('timeLeft').innerHTML = 'Click again in ' + countdownNum;
countdownNum--;
setTimeout(function(){
// Note that the whole timeout was moved inside,
// Imagine this is recursive function, with a delay.
incTimer();
}, 1000);
} else {
document.getElementById('timeLeft').innerHTML = '';
document.getElementById('btnOne').disabled = false;
}
}
}
There are better ways to express your code, but I tried to stick as much as possible to your code style.

How would I toggle the state of a setInterval function in jQuery?

I want to be able to click a an element with an id of pause to start a count of the elements in a time object and if I re click the pause it will stop it and reclick start it exactly like the toggle feature in JQuery but with a setInteval function how would I go about doing this?
$("#pause").click(function(ffe) {
if(on == true) {
on = false
alert("on");
}
else {
on = true;
alert("off");
}
if(on == false) {
setInterval(function() {
$("#timet ul").append("<li>" + $("#time ul")
.children('li').length +"</li>");
}, 100);
}
else {
alert("Error");
}
});
A classic technique is to use a single master setInterval loop and simply use if..else logic to determine what needs to run. This is how a lot of javascript games work:
var on = true;
// Our master scheduler:
setInterval(function() {
if (on) {
$("#timet ul").append("<li>" + $("#time ul")
.children('li').length +"</li>");
}
}, 100);
// Code to handle the pause button
$("#pause").click(function(ffe) {
on = !on;
}
You can use the setTimeout function, if you want to run the function once, setInterval runs continuously, try the following:
var on = false;
$("#pause").click(function(ffe) {
if (on) {
on = false;
setTimeout(function() {
$("#timet ul").append("<li>" + $("#time ul")
.children('li').length +"</li>");
}, 100);
} else {
on = true;
}
});
You need to use .clearInterval() to stop the execution.
Here is the code: (THE WORKING DEMO)
$("#pause").click((function () {
var interId = null;
var $ul = $("#timet ul");
return function (e) {
if (interId) {
$(this).text("start");
clearInterval(interId);
interId = null;
} else {
$(this).text("pause");
interId = setInterval(function () {
$ul.append($('<li>').text($('li', $ul).length));
}, 100);
}
};
}()));​

How to activate setInterval() incase a text control has the focus

Actually I have an update enquery into this point .
I have smth like that :
$(document).ready(function() {
setInterval(doSmth, 10000);
function doSmth() {
var result = document.getElementById("fooText").value;
if (result != "") {
doSmthElse(result);
}
});
}
}
});
I need to activate the interval ,that is fired each 10 seconds, in case only a text control has the focus else do nothing !!
Code for you is:
$(document).ready(function() {
setInterval(function(){
var result = $("#fooText").val();
if (result != "") {
// if
} else {
// else
}
}, 10000);
You can set the interval on focus of the field, and clear it on blur:
var interval;
$(field).focus(function() {
interval = setInterval(doMsth, 10000);
});
$(field).blur(function() {
clearInterval(interval);
});
(the interval var has to be global)
You can implement this in 2 ways,
Let the timer run and inside the function check if the activeElement == <text input>, then execute the rest of the function else return.
$(document).ready(function() {
setInterval(doSmth, 5000);
function doSmth() {
var resultEl = document.getElementById("fooText");
if (document.activeElement.id != resultEl.id) { return false; }
if (resultEl.value != "") {
doSmthElse(resultEl.value);
}
}
function doSmthElse(result) { alert(result);}
});
DEMO here
Set the timer on focus of the text box and remove the timer onblur of the input box.
$('#fooText').focus ( function () {
timer = setInterval(function() {
var textVal = $('#fooText').val();
if (textVal != '') {
doSmthElse(textVal );
}
}, 5000);
});
$('#fooText').blur (function () {
if (timer != '') clearInterval(timer);
});
DEMO here

How can I re enable a setInterval after I called clearInterval?

Here's my javascript:
<script type="text/javascript">
var timer;
$(document).ready(function () {
timer = setInterval(updatetimerdisplay, 1000);
$('.countdown').change(function () {
timer = setInterval(updatetimerdisplay, 1000);
});
function updatetimerdisplay() {
$(".auctiondiv .auctiondivleftcontainer .countdown").each(function () {
var newValue = parseInt($(this).text(), 10) - 1;
$(this).text(newValue);
if (newValue >= 9) {
$(this).css("color", "");
$(this).css("color", "#4682b4");
}
if (newValue == 8) {
$(this).css("color", "");
$(this).css("color", "#f3982e");
}
if (newValue == 5) {
$(this).css("color", "");
$(this).css("color", "Red");
}
if (newValue <= 1) {
//$(this).parent().fadeOut();
clearInterval(timer);
}
});
}
});
var updateauctionstimer = setInterval(function () {
$("#refreshauctionlink").click();
}, 2000);
function updateauctions(response) {
var data = $.parseJSON(response);
$(data).each(function () {
var divId = "#" + this.i;
if ($(divId + " .auctiondivrightcontainer .latestbidder").text() != this.b) {
$(divId + " .auctiondivrightcontainer .latestbidder").fadeOut().fadeIn();
$(divId + " .auctiondivrightcontainer .auctionprice .actualauctionprice").fadeOut().fadeIn();
$(divId + " .auctiondivleftcontainer .countdown").fadeOut().fadeIn();
}
$(divId + " .auctiondivrightcontainer .latestbidder").html(this.b);
$(divId + " .auctiondivrightcontainer .auctionprice .actualauctionprice").html(this.p);
if ($(divId + " .auctiondivleftcontainer .countdown").text() < this.t) {
$(divId + " .auctiondivleftcontainer .countdown").html(this.t);
}
});
}
</script>
Basically, I want to turn the timer back on, if any .countdown element has it's text change.
The text will change because of an AJAX call I use to update that value.
Currently the timer doesn't re enable and the countdown freezes after the value of .Countdown is changed. I think that the change() event fires when the text of an element changes. Is this correct?
Any glaring mistakes on my part?
Your code contains a loop and condition:
function updatetimerdisplay() {
$(".auctiondiv .auctiondivleftcontainer .countdown").each(function () {
...
if (newValue <= 1) {
//$(this).parent().fadeOut();
clearInterval(timer);
}
...
}
}
It's very likely that one of these elements have a value which satisfy the condition newValue <= 1. In that case, the timer will stop. Even when you change the contents of an input field, the timer will immediately stop after that run.
If you have to support multiple timers, use a wallet of timers (var timers = {};timers.time1=... or var timers = [];timers[0] = ...). If you have to support only a few timeouts, you can even use variables (var timer1=... ,timer2=..., timer3=...;).
You are trying to bind the change event before the elements exist. Put that code inside the ready event handler:
$(document).ready(function () {
timer = setInterval(updatetimerdisplay, 1000);
$('.countdown').change(function () {
timer = setInterval(updatetimerdisplay, 1000);
});
});
You also might want set the timer variable to an identifiable value when the timer is off (e.g. null), so that you can check for that value before you start a timer to prevent from starting multiple timers.

Categories

Resources