Search code examples
javascriptjqueryformsradio-button

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);
  });
});

Solution

  • 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