Reputation: 997
I'm trying to transform this loop that changes the value of a varible number of inputs:
$("#wrap input").each(function( index ) {
for( i = 10 ; i > 0 ; i--) {
$(this).val(i);
console.log( index + ": " + $(this).val() );
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrap">
<input type="text">
<input type="text">
<input type="text">
</div>
I need to have a small delay between each iteration. I'm trying some variatons of this:
$("#wrap input").each(function( index ) {
var a = $(this);
var i = 10;
var loop = setInterval(function() {
a.val(i);
console.log( index + ": " + a.val() );
i--;
if(i==0) clearInterval( loop );
},1000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrap">
<input type="text">
<input type="text">
<input type="text">
</div>
It doesn't work like I need.
I need to change the value in order, first input changes to 10 (delay) changes to 9 (delay)... second input changes to 10 (delay) changes to 9 (delay)... and so on. Hope you get the idea.
I'm thinking to assign them different ids via jQuery and then make a loop through each one separately, but I need a script as brief as possible.
I'm a little stuck, I appreciate any hint.
Final update: @acontell gave a perfect answer for the example I was dealing with in my question. Yet I realized why I didn't use next() since the begginnig: in the real project the inputs are not immediate siblings, they are each inside a couple of containers. Anyway the loop proposed by @acontell suits fine, I just had to put the elements in an array, like this:
var list = [];
$("#wrap input").each(function(index) {
list.push($(this));
});
var i = 10; // Countdown start
var n = 0; // Array index
var loop = setInterval(function() {
if (n > list.length - 1) {
clearInterval(loop);
} else {
list[n].val(i--);
if (i < 0) {
n++;
i = 10;
}
}
}, 100);
<div id="wrap">
<div><div><div><input type="text"></div></div></div>
<div><div><div><input type="text"></div></div></div>
<div><div><div><input type="text"></div></div></div>
<div><div><div><input type="text"></div></div></div>
<div><div><div><input type="text"></div></div></div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Upvotes: 1
Views: 97
Reputation: 6922
I'm not really sure of what you're after, but if you want to wait for each counter (in each input) to finish and then start the next counter, a linked list comes to mind.
Jquery provides the method next that gets you the next sibling. That could help you to build the linked list. The iteration over the list could be done using an interval that would be cleared when there were no more siblings. Putting it all together:
var $element = $("#wrap input:first"),
countdownLimit = 10;
var loop = setInterval(function() {
if (!$element.length) {
clearInterval(loop);
} else {
$element.val(countdownLimit--);
if (countdownLimit < 0) {
$element = $element.next('input');
countdownLimit = 10;
}
}
}, 1000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrap">
<input type="text">
<input type="text">
<input type="text">
</div>
There can be as many inputs as you like as long as they all are siblings.
Upvotes: 1
Reputation: 3358
Any time you need to have a delay in iterations, it makes sense to use a self-calling function instead of a loop.
function doStuff(data, i){
//do things here
console.log(i)
if(--i) setTimeout(function(){doStuff(data, i)}, 1000)
else nextStep(data)
}
function nextStep(data){
//after the loop ends, move to the next step of your code
}
doStuff([], 10)
Upvotes: 1
Reputation:
Have you tried the equivalent of thread sleep?
var millisecondsToWait = 500;
setTimeout(function() {
// Whatever you want to do after the wait
}, millisecondsToWait);
Upvotes: 0