3
votes

I need some help with Swiper. According to its documentation here: http://idangero.us/swiper/api/, I need to call mySwiper.update() after I hide/show slides manually. But it does not always work in my case.

I've searched this issue, but only came across following solutions which should but for some reason do not work:

  1. mySwiper.update() as I mentioned before
  2. observer: true, observeParents: true when initializing swiper.

Perhaps something wrong with my jQuery code, but I can't figure it out.

This is how I initialize Swiper, as I need 2 rows and 3 columns to display data.

var swiper = new Swiper('.swiper-container', {
        slidesPerView: 3,
        slidesPerColumn: 2,
        spaceBetween: 30,
        observer: true,
        observeParents: true,
        navigation: {
          nextEl: '.swiper-button-next',
          prevEl: '.swiper-button-prev',
        },
        pagination: {
          el: '.swiper-pagination',
          clickable: true,
        },
      });

The Swiper wrapper goes like this in HTML:

<div class="swiper-wrapper " id="plugins_list">
          <div class="swiper-slide Category1 uk-animation-slide-top-medium">
            <div class="uk-card uk-card-body">
              <div class="uk-inline uk-slider-items uk-transition-toggle">
                <img src="./images/plu2.jpg" alt="">
                <div class="uk-overlay uk-overlay-primary uk-position-bottom">
                  <p>Default Lorem ipsum dolor sit amet.</p>
                </div>
              </div>
            </div>
          </div>
          <div class="swiper-slide Category1 uk-animation-slide-top-medium">
            <div class="uk-card uk-card-body">
              <div class="uk-inline uk-slider-items uk-transition-toggle">
                <img src="./images/plu2.jpg" alt="">
                <div class="uk-overlay uk-overlay-primary uk-position-bottom">
                  <p>Default Lorem ipsum dolor sit amet.</p>
                </div>
              </div>
            </div>
          </div>
          <div class="swiper-slide Category2 uk-animation-slide-top-medium">
            <div class="uk-card uk-card-body">
              <div class="uk-inline uk-slider-items uk-transition-toggle">
                <img src="./images/plu2.jpg" alt="">
                <div class="uk-overlay uk-overlay-primary uk-position-bottom">
                  <p>Default Lorem ipsum dolor sit amet.</p>
                </div>
              </div>
            </div>
          </div>
</div>

And this is how I want to update the wrapper:

// 'category1' button/tab selector
$('#category1').on('click', function() {
        $('.swiper-slide').hide();
        $('.Category1').show();
        swiper.update(true);
      });
// category2 button/tab selector 
      $('#category2').on('click', function() {
        $('.swiper-slide').hide();
        $('.Category1').show();
        swiper.update();
      });
// 'All' button/tab selector - to show all slides, this i use only to show animation that all slides were loaded, this is working fine every time with swiper update
      $('#all').on('click', function() {
        $('.swiper-slide').hide();
        $('.swiper-slide').show();
        swiper.update();
      });

Any ideas? Or how should I show/hide the the slides differently? Please let me know.

And in case the problem isn't clear, I am calling swiper.update() so the slide positions are updated, as when the slides are filtered (hidden/shown) the remaining ones are displayed out of position.

2
​Got the swiper.update() working by setting slidesPerColumn to 1, guess this is a bug in the swiper plugin​. and have to compromise on design.MSKH

2 Answers

0
votes

Swiper saves data-swiper-column and data-swiper-row based on all items, for some reason ignoring display: none. My solution is to remove all items, and then insert the only HTML of needed items (each time something changes). I really have no idea if this is a good way regarding memory and performance, but it works.

// slides to variable
var allSlides = $(".swiper-slide"); 

// remove from DOM
$(".swiper-slide").remove();

// Generate new html
allSlides.each(function(e){ 
    $("#plugins_list").append($(this)[0].outerHTML);
});

// init swiper
var swiper = new Swiper( ... );

$('#category1').on('click', function() {
    //remove from DOM
    $(".swiper-slide").remove();

    // Generate new html, only slides we want
    allSlides.each(function(){
        if($(this).is(".Category1")) { 
            $("#plugins_list").append($(this)[0].outerHTML);
        }
    });

    //update slides
    swiper.update();
});
0
votes

swiper slides inherit their swiper wrapper styles like code below.

<div class="swiper-wrapper" style="display:none" >
  <div class="swiper-slide" style="display:none" > // this style is inherited from paret while initing swiper
  </div>
</div>

first of all use visibility hidden in echange with display none. two solutions you can use first:

$('.swiper-container-class').find('swiper-slide').css('visibility','visible');

this way all child elements will also be visible.

second using css:

.swiper-slides{ visibility: inherit !important; }

for animation you can use opacity.