javascriptjquerycarouselslick.js

How to maintain the selected state of radio button in slick slides as you navigate between slides


Steps to do.

  1. Select the radio button item 1.
  2. Click the slick next arrow until you reach again the item 1 and it is not selected. I want it selected because you select it previously.

I want to maintain the selected state of radio button in slick slides once it shown in the slick/viewport.

I tried using the slick Methods and Events like slickGoTo, afterChange ect.. but no to avail.

Here are my codes.

$('.my-slick-carousel').each(function() {
        let slider = $(this);
        slider.slick({
            slidesToShow: 1,
            slidesToScroll: 1,
            autoplay: false,
            dots: true,
            infinite: true,
            arrows: true,
            centerPadding: '0px',
            variableWidth: true,
            centerMode: false,
            touchThreshold: 100,
            rows: 0,
        });
    });
.items {
  width: 380px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick-theme.min.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.min.js"></script>
<style>
.items {
  background-color: gray;
  border-radius:2rem;
  text-align:center;
}
.slick-prev,
.slick-next {
  z-index:9;
}
.slick-next:before, .slick-prev:before {
  color: red;
}
.slick-prev {
  left: 0;
}
.slick-next {
  right: 0;
}
</style>

<div class="container">
  <h4 class="text-center">Maintain the selected radio button on slick slide and maintain the selected state as you navigate between slides.</h4>
<div class="my-slick-carousel py-5 px-3">
    <div class="items mx-2 p-4"><input type="radio" name="addOnsRadio" value="item 1" id=""> item 1</div>
    <div class="items mx-2 p-4"><input type="radio" name="addOnsRadio" value="item 2" id=""> item 2</div>
    <div class="items mx-2 p-4"><input type="radio" name="addOnsRadio" value="item 3" id=""> item 3</div>
     <div class="items mx-2 p-4"><input type="radio" name="addOnsRadio" value="item 4" id=""> item 4</div>
     <div class="items mx-2 p-4"><input type="radio" name="addOnsRadio" value="item 5" id=""> item 5</div>
  </div>
</div>


Solution

  • You can listen to the slide change event afterChange and set :checked on the cloned slide:

    $('.my-slick-carousel').each(function () {
      let slider = $(this);
      slider.slick({
        slidesToShow: 2,
        slidesToScroll: 1,
        autoplay: false,
        dots: true,
        infinite: true,
        arrows: true,
        centerPadding: '0px',
        variableWidth: true,
        centerMode: false,
        touchThreshold: 100,
        rows: 0,
      });
    });
    
    $(document).on('change', '.my-slick-carousel [type="radio"]', function () {
      const t = $(this);
      t.closest('.my-slick-carousel').data('value', t.val());
    });
    
    $('.my-slick-carousel').on('afterChange', function () {
      const t = $(this);
      const checkedInput = t.find('[type="radio"]:checked');
      if (!checkedInput.length) {
        return;
      }
      const value = t.data('value');
      let isActive = false;
      t.find('.slick-slide').each(function () {
        const slide = $(this);
        if (slide.hasClass('slick-active')) {
          isActive = true;
        }
        if (!isActive) {
          return;
        }
        checkedInput.prop('checked', false);
        const input = slide.find('[type="radio"]');
        if (input.val() === value) {
          input.prop('checked', true);
          return false;
        }
      });
    });
    <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css" rel="stylesheet"/>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.min.css" rel="stylesheet"/>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick-theme.min.css" rel="stylesheet"/>
    <script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.min.js"></script>
    <style>
    .items {
      background-color: gray;
      border-radius:2rem;
      text-align:center;
    }
    .slick-prev,
    .slick-next {
      z-index:9;
    }
    .slick-next:before, .slick-prev:before {
      color: red;
    }
    .slick-prev {
      left: 0;
    }
    .slick-next {
      right: 0;
    }
    .items {
      width: 380px;
    }
    </style>
    
    <div class="container">
      <h4 class="text-center">Maintain the selected radio button on slick slide and maintain the selected state as you navigate between slides.</h4>
      <div class="my-slick-carousel py-5 px-3">
        <div class="items mx-2 p-4"><input type="radio" name="addOnsRadio" value="item 1" id=""> item 1</div>
        <div class="items mx-2 p-4"><input type="radio" name="addOnsRadio" value="item 2" id=""> item 2</div>
        <div class="items mx-2 p-4"><input type="radio" name="addOnsRadio" value="item 3" id=""> item 3</div>
        <div class="items mx-2 p-4"><input type="radio" name="addOnsRadio" value="item 4" id=""> item 4</div>
        <div class="items mx-2 p-4"><input type="radio" name="addOnsRadio" value="item 5" id=""> item 5</div>
      </div>
    </div>