I'm trying to iterate through radio buttons automatically every 5 seconds via jquery; however i need the function to also run when i manually switch buttons. Here's what I have so far:
$(document).ready(function () {
(function news() {
if ($('#pabnews_slide1').is(':checked')) {
$('#pabnews_slide2').prop('checked', true)
}
else if ($('#pabnews_slide2').is(':checked')) {
$('#pabnews_slide3').prop('checked', true)
}
else if ($('#pabnews_slide3').is(':checked')) {
$('#pabnews_slide4').prop('checked', true)
}
else if ($('#pabnews_slide4').is(':checked')) {
$('#pabnews_slide1').prop('checked', true)
}
setTimeout(news, 5000);
})();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<input name="slideshow" id="pabnews_slide1" type="radio" checked />
<label for="pabnews_slide1">A</label>
<input name="slideshow" id="pabnews_slide2" type="radio"/>
<label for="pabnews_slide2">B</label>
<input name="slideshow" id="pabnews_slide3" type="radio" />
<label for="pabnews_slide3">C</label>
<input name="slideshow" id="pabnews_slide4" type="radio" />
<label for="pabnews_slide4">D</label>
which works, but my issue is that the function is called every 5 secs and the timer does not go back to 0 when i manually switch buttons. How would you go about doing that?
To be clearer, in the current state, when you wait 3 seconds and manually switch button, the function is called only 2 seconds afterwards and I would need to make it 5.
Here is a vanilla JS example though I did add a dataset attribute to your HTML to track the number of the elements being changed and to use in selecting the changed
element one would select. I also refactored the function that increments through the list of elements and changes the checked
element.
First we get the a list of the input elements using the name tag.
Then we set an incrementer, i
, to match the dateset and index of each element within a loop.
Because we want to track which element is currently being selected and which element the setTimeout is on, we will track these with variables currentSlide
and SelectedSlide
. Then we instantiate an empty variable to track the timeout timer
.
Now we run logic in a function to change the element using the incrementer and the list of input elements, if i
is greater than the list of elements length
reset i
to 0. Then we track the value of selectedSlide
, if it is set, we set the value of i
to its dataset.id
.
Now, keep in mind that selectedSlide
is set within the method/function setCurrentSlide(e)
which tracks the event.target
being changed to. Within that function we run clearTimeout(timer)
which clears the setTimeout()
and we re-instantiate the timer
passing in the selectedSlide
element so we can get its dataset.id
and use that to set the loop to the proper element to start at when we call the changeSlide()
method/function.
currentSlide
is set using i
on the list of elements slides
=> currentSlide = slides[i]
Lastly, we use the list of elements slides
to run an eventListener that listens for a change
event. Here we call the set setCurrentSlide
method/function, which again uses the event.target
=> e.target
to retrieve the dataset.id
. Then we set that elements checked attribute to true
.
We then set the value of timer
using a setTimeout(), passing in the changeSlide
function and setting its delay.
Lastly we increment i
by 1, i++
.
Let me know if anything is not making sense and I hope this helps out. I left notes within the code to help understand what each line is doing.
$(document).ready(function() {
// get all the slides elements
const slides = document.querySelectorAll('input[name="slideshow"]');
// set an incrementer
let i = 0;
// instantiate empty variables
var currentSlide, selectedSlide, timer;
// method to changeEach slide to the next in line and reset to
function changeSlide(currentSlide, selectedSlide){
// ternary conditional, sets i to 0 if it has reached the last element
i > slides.length-1 ? i = 0 : null;
// ternary conditional, sets the selectedSlide if it is passed as a param
selectedSlide ? i = selectedSlide.dataset.id : null;
// set the current element to the indexed incrementer
currentSlide = slides[i];
// checks the proper element using the checked attribute
currentSlide.checked = true;
// define timer and call the changeSlide method and set delay
timer = setTimeout(changeSlide, 5000);
// increment i by 1
i++;
}
// method to set current element
// uses the eventTarget passed from the eventListener
function setCurrentSlide(e){
// clear the timeout
clearTimeout(timer);
// set the selectedSlide variable to the event.target
selectedSlide = e.target;
// run the changeSlide method again using the event.target as reference as selectedSlide param
changeSlide(currentSlide, selectedSlide);
}
// iterate over the slides elements
slides.forEach(slide => {
// event listener listens for a change and runs the setCurrentSlide method
slide.addEventListener('change', setCurrentSlide);
});
// run the changeSlide method
changeSlide(currentSlide, selectedSlide);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<input name="slideshow" id="pabnews_slide1" data-id="0" type="radio" checked />
<label for="pabnews_slide1">A</label>
<input name="slideshow" id="pabnews_slide2" data-id="1" type="radio" />
<label for="pabnews_slide2">B</label>
<input name="slideshow" id="pabnews_slide3" data-id="2" type="radio" />
<label for="pabnews_slide3">C</label>
<input name="slideshow" id="pabnews_slide4" data-id="3" type="radio" />
<label for="pabnews_slide4">D</label>