LearntoExcel LearntoExcel - 1 year ago 42
jQuery Question

Radio Input Control with External Button

Hello I am making a slideshow out of a radio input and have designed "prev" and "next" buttons to move the slide along. However, I would also like the buttons to also check the next input. Currently the slide moves, but the next input isn't checked. I have looked at this solution here:
Select next/prev radio button with external button
and tried to implement it but I cannot get it to work. Here is my code:

<form action="" method="post">
<ul class="form-ul" style="position: relative; width: 176px; height: 107px;">
<li style="position: absolute; top: 0px; left: 0px; display: block; z-index: 5; opacity: 1; width: 82px; height: 43px;">
<label>
<input type="radio" name="term_id" value="59" checked="checked">
</label>
</li>
<li style="position: absolute; top: 0px; left: 0px; display: none; z-index: 4; opacity: 0; width: 82px; height: 62px;">
<label>
<input type="radio" name="term_id" value="61">
</label>
</li>
</ul>
<div id="prev" style="float:left;">PREV</div>
<div id="next" style="float:right;">NEXT</div>
</form>


JavaScript:

$(document).ready(function(){
$('#prev').click(function(){
$('.form-ul').find('li:has(input:checked)').prev().children('input').prop("checked", true);
});

$('#next').click(function(){
$('.form-ul').find('li:has(input:checked)').next().children('input').prop("checked", true);
});
});

Answer Source

jQuery's .children() only finds the immediate children of an element. In your case, the radio buttons are not the immediate children, so you need to change it to .find():

$(document).ready(function(){
  $('#prev').click(function(){
      $('.form-ul').find('li:has(input:checked)').prev().find('input').prop("checked", true);
  });

  $('#next').click(function(){
      $('.form-ul').find('li:has(input:checked)').next().find('input').prop("checked", true);
  });
});

Also, you can improve performance by making less queries. Instead of

$('.form-ul).find('li:has(input:checked)')

use

$('.form-ul li:has(input:checked)')

To make it circular, check against the length of the result set:

$('#next').click(function(){
  var $next = $('.form-ul li:has(input:checked)').next();
  if(!$next.length) $next = $('.form-ul li').first();
  $next.find('input').prop("checked", true);
});

Here is a fiddle and a circular fiddle