1
votes

i'm using Swiper JS and i'm struggling to find a way in which I can remove duplicates from the pagination. I want the ability to have a slide for each year with content inside, but also have multiple slides for a particular year - BUT only writing 1 pagination for it (with the nav/swipe working).

So if the slides where:

1989, 1990, 1992, 1992, 1992

Then the pagination would show as:

1989, 1990, 1992

(also the swipe and left/right arrows would work with this and scroll through all slides not missing any, but staying on the 1992 for each duplicate).

<div class="swiper-container">
    <!-- Additional required wrapper -->
    <div class="swiper-wrapper">
        <!-- Slides -->
        <div class="swiper-slide" year="1989">Content</div>
      <div class="swiper-slide" year="1990">Content</div>
      <div class="swiper-slide" year="1992">Content</div>
                  <div class="swiper-slide" year="1992">Content</div>
                  <div class="swiper-slide" year="1992">Content</div>
               <div class="swiper-slide" year="1993">Content</div>
    </div>
    <!-- If we need pagination -->
    <div class="swiper-pagination"></div>

    <!-- If we need navigation buttons -->
    <div class="swiper-button-prev"></div>
    <div class="swiper-button-next"></div>
</div>
var mySwiper = new Swiper ('.swiper-container', {
    // If we need pagination
    pagination: {
      el: '.swiper-pagination',
            clickable: true,
        renderBullet: function (index, className) {
          return '<span class="' + className + '">' + (menu[index]) + '</span>';
        },
    },

    // Navigation arrows
    navigation: {
      nextEl: '.swiper-button-next',
      prevEl: '.swiper-button-prev',
    },
  })

Here is a clean example with the duplicate years:

https://codepen.io/nolimit966/pen/XWXNNqR

Things I have tried so far:

Finding the duplicate years and removing them from the menu - The main problem with this is now is skips that slide.

Removing the duplicate dom pagination element - this then looks broken when swiping though as theres a point when no pagination is highlighted.

Can anyone help me to understand how I can achieve this?

1

1 Answers

2
votes

You can achieve this by implementing your own logic. Meaning that you handle clicks on prev, next and year elements.

The version you are using is old which is why I used trigger on .timeline element. The new version of swiperjs has slideChange event which you can utilize to achieve the same result.

You can find fiddle here: https://jsfiddle.net/3ryo71m5/.

And here is an example:

var years = [];
let slideIndex = 0;
let currentSlide = 0;

var timelineSwiper = new Swiper('.timeline .swiper-container', {
  direction: 'vertical',
  loop: false,

  speed: 1600,
  pagination: '.swiper-pagination',
  paginationBulletRender: function(swiper, index, className) {
    let el = swiper.slides[index];
    var yearValue = el.getAttribute('year');

    if (!years.includes(yearValue)) {
      // Set data attribute to slides to link to year element
      el.setAttribute("data-parent", index);

      // Use this var for next iteration to group similar slides
      slideIndex = index;
      years.push(yearValue);
      let clsName = index == 0 ? "swiper-pagination-bullet-custom swiper-pagination-bullet-custom-active" : "swiper-pagination-bullet-custom";


      return `<span class="${clsName}" data-index='${index}'>${yearValue}</span>`;
    }
    el.setAttribute("data-parent", slideIndex);
    return "";
  },
  paginationClickable: false,

  breakpoints: {
    768: {
      direction: 'horizontal',
    }
  }
});

// Handle click on next arrow if not reached the end of slider
$(".swiper-button-next").on("click", function() {
  if (!timelineSwiper.isEnd) {
    timelineSwiper.slideTo(++currentSlide);
    $(".timeline").trigger("slideChange");
  }
});


// Handle click on prev arrow if not reached the beginning of slider
$(".swiper-button-prev").on("click", function() {
  if (!timelineSwiper.isBeginning) {
    timelineSwiper.slideTo(--currentSlide);
    $(".timeline").trigger("slideChange");
  }
});

// Handle click on years
$(".swiper-pagination span").on("click", function() {
  let el = $(this);
  let pageIndex = el.attr("data-index");
  timelineSwiper.slideTo(pageIndex);
  $(".timeline").trigger("slideChange");
  currentSlide = pageIndex;

});

// On slide change move active class to relevant element
$(".timeline").on("slideChange", function() {
  $(".swiper-pagination-bullet-custom-active").removeClass("swiper-pagination-bullet-custom-active");

  let active = timelineSwiper.activeIndex;
  let index = timelineSwiper.slides[active].getAttribute("data-parent");

  $(`.swiper-pagination span[data-index="${index}"]`).addClass("swiper-pagination-bullet-custom-active");
});
html,
body,
.container {
  height: 100%;
}

body {
  font-family: "Open Sans", sans-serif;
  font-size: 14px;
}

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #fff;
  flex-direction: column;
}

.title {
  font-size: 38px;
  color: #616161;
  font-style: italic;
  font-weight: 800;
}

.timeline {
  width: 100%;
  background-color: #fff;
  box-shadow: 0 5px 25px 5px rgba(0, 0, 0, 0.2);
}

.timeline .swiper-container {
  height: 600px;
  width: 100%;
  position: relative;
}

.timeline .swiper-wrapper {
  transition: 2s cubic-bezier(0.68, -0.4, 0.27, 1.34) 0.2s;
}

.timeline .swiper-slide {
  position: relative;
  color: #fff;
  overflow: hidden;
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center center;
}

.timeline .swiper-slide::after {
  content: "";
  position: absolute;
  z-index: 1;
  right: -115%;
  bottom: -10%;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.7);
  box-shadow: -230px 0 150px 60vw rgba(0, 0, 0, 0.7);
  border-radius: 100%;
}

.timeline .swiper-slide-content {
  position: absolute;
  text-align: center;
  width: 80%;
  max-width: 310px;
  right: 50%;
  top: 13%;
  transform: translate(50%, 0);
  font-size: 12px;
  z-index: 2;
}

.timeline .swiper-slide .timeline-year {
  display: block;
  font-style: italic;
  font-size: 42px;
  margin-bottom: 50px;
  transform: translate3d(20px, 0, 0);
  color: #d4a024;
  font-weight: 300;
  opacity: 0;
  transition: 0.2s ease 0.4s;
}

.timeline .swiper-slide .timeline-title {
  font-weight: 800;
  font-size: 34px;
  margin: 0 0 30px;
  opacity: 0;
  transform: translate3d(20px, 0, 0);
  transition: 0.2s ease 0.5s;
}

.timeline .swiper-slide .timeline-text {
  line-height: 1.5;
  opacity: 0;
  transform: translate3d(20px, 0, 0);
  transition: 0.2s ease 0.6s;
}

.timeline .swiper-slide-active .timeline-year {
  opacity: 1;
  transform: translate3d(0, 0, 0);
  transition: 0.4s ease 1.6s;
}

.timeline .swiper-slide-active .timeline-title {
  opacity: 1;
  transform: translate3d(0, 0, 0);
  transition: 0.4s ease 1.7s;
}

.timeline .swiper-slide-active .timeline-text {
  opacity: 1;
  transform: translate3d(0, 0, 0);
  transition: 0.4s ease 1.8s;
}

.timeline .swiper-pagination {
  right: 15% !important;
  height: 100%;
  display: none;
  flex-direction: column;
  justify-content: center;
  font-style: italic;
  font-weight: 300;
  font-size: 18px;
  z-index: 1;
}

.timeline .swiper-pagination::before {
  content: "";
  position: absolute;
  left: -30px;
  top: 0;
  height: 100%;
  width: 1px;
  background-color: rgba(255, 255, 255, 0.2);
}

.timeline .swiper-pagination-bullet-custom {
  width: auto;
  height: auto;
  text-align: center;
  opacity: 1;
  background: transparent;
  color: #d4a024;
  margin: 15px 0 !important;
  position: relative;
  cursor: pointer;
}

.timeline .swiper-pagination-bullet-custom::before {
  content: "";
  position: absolute;
  top: 8px;
  left: -32.5px;
  width: 6px;
  height: 6px;
  border-radius: 100%;
  background-color: #d4a024;
  transform: scale(0);
  transition: 0.2s;
}

.timeline .swiper-pagination-bullet-custom-active {
  color: #d4a024;
}

.timeline .swiper-pagination-bullet-custom-active::before {
  transform: scale(1);
}

.timeline .swiper-button-next,
.timeline .swiper-button-prev {
  background-size: 20px 20px;
  top: 15%;
  width: 20px;
  height: 20px;
  margin-top: 0;
  z-index: 2;
  transition: 0.2s;
}

.timeline .swiper-button-prev {
  left: 8%;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23d4a024'%2F%3E%3C%2Fsvg%3E");
}

.timeline .swiper-button-prev:hover {
  transform: translateX(-3px);
}

.timeline .swiper-button-next {
  right: 8%;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23d4a024'%2F%3E%3C%2Fsvg%3E");
}

.timeline .swiper-button-next:hover {
  transform: translateX(3px);
}

@media screen and (min-width: 768px) {
  .timeline .swiper-slide::after {
    right: -30%;
    bottom: -8%;
    width: 240px;
    height: 50%;
    box-shadow: -230px 0 150px 50vw rgba(0, 0, 0, 0.7);
  }
  .timeline .swiper-slide-content {
    right: 30%;
    top: 50%;
    transform: translateY(-50%);
    width: 310px;
    font-size: 11px;
    text-align: right;
  }
  .timeline .swiper-slide .timeline-year {
    margin-bottom: 0;
    font-size: 32px;
  }
  .timeline .swiper-slide .timeline-title {
    font-size: 46px;
    margin: 0;
  }
  .timeline .swiper-pagination {
    display: flex;
  }
  .timeline .swiper-button-prev {
    top: 15%;
    left: auto;
    right: 15%;
    transform: rotate(90deg) translate(0, 10px);
  }
  .timeline .swiper-button-prev:hover {
    transform: rotate(90deg) translate(-3px, 10px);
  }
  .timeline .swiper-button-next {
    top: auto;
    bottom: 15%;
    right: 15%;
    transform: rotate(90deg) translate(0, 10px);
  }
  .timeline .swiper-button-next:hover {
    transform: rotate(90deg) translate(3px, 10px);
  }
}

@media screen and (min-width: 1024px) {
  .timeline .swiper-slide::after {
    right: -20%;
    bottom: -12%;
    width: 240px;
    height: 50%;
    box-shadow: -230px 0 150px 39vw rgba(0, 0, 0, 0.7);
  }
  .timeline .swiper-slide-content {
    right: 25%;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/3.4.2/js/swiper.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/3.4.2/css/swiper.min.css" rel="stylesheet" />
<div class="container">
  <h1 class="title">Responsive Slider Timeline</h1>
  <div class="timeline">
    <div class="swiper-container">
      <div class="swiper-wrapper">
        <div class="swiper-slide" style="background-image: url(https://unsplash.it/1920/500?image=11" year="2011">
          <div class="swiper-slide-content"><span class="timeline-year">2011</span>

            <h4 class="timeline-title">Our nice super title</h4>
            <p class="timeline-text">Lorem ipsum dolor site amet, consectetur adipscing elit, sed do eisumod tempor incididut ut labore et dolore magna aliqua. Ut enim ad mimim venjam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
          </div>
        </div>
        <div class="swiper-slide" style="background-image: url(https://unsplash.it/1920/500?image=11" year="2011">
          <div class="swiper-slide-content"><span class="timeline-year">2011</span>

            <h4 class="timeline-title">Our nice super title</h4>
            <p class="timeline-text">Lorem ipsum dolor site amet, consectetur adipscing elit, sed do eisumod tempor incididut ut labore et dolore magna aliqua. Ut enim ad mimim venjam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
          </div>
        </div>
        <div class="swiper-slide" style="background-image: url(https://unsplash.it/1920/500?image=11" year="2011">
          <div class="swiper-slide-content"><span class="timeline-year">2011</span>

            <h4 class="timeline-title">Our nice super title</h4>
            <p class="timeline-text">Lorem ipsum dolor site amet, consectetur adipscing elit, sed do eisumod tempor incididut ut labore et dolore magna aliqua. Ut enim ad mimim venjam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
          </div>
        </div>
        <div class="swiper-slide" style="background-image: url(https://unsplash.it/1920/500?image=12" year="2012">
          <div class="swiper-slide-content"><span class="timeline-year">2012</span>
            <h4 class="timeline-title">Our nice super title</h4>
            <p class="timeline-text">Lorem ipsum dolor site amet, consectetur adipscing elit, sed do eisumod tempor incididut ut labore et dolore magna aliqua. Ut enim ad mimim venjam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
          </div>
        </div>
        <div class="swiper-slide" style="background-image: url(https://unsplash.it/1920/500?image=13" year="2013">
          <div class="swiper-slide-content"><span class="timeline-year">2013</span>
            <h4 class="timeline-title">Our nice super title</h4>
            <p class="timeline-text">Lorem ipsum dolor site amet, consectetur adipscing elit, sed do eisumod tempor incididut ut labore et dolore magna aliqua. Ut enim ad mimim venjam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
          </div>
        </div>
        <div class="swiper-slide" style="background-image: url(https://unsplash.it/1920/500?image=14" year="2014">
          <div class="swiper-slide-content"><span class="timeline-year">2014</span>
            <h4 class="timeline-title">Our nice super title</h4>
            <p class="timeline-text">Lorem ipsum dolor site amet, consectetur adipscing elit, sed do eisumod tempor incididut ut labore et dolore magna aliqua. Ut enim ad mimim venjam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
          </div>
        </div>
        <div class="swiper-slide" style="background-image: url(https://unsplash.it/1920/500?image=15" year="2015">
          <div class="swiper-slide-content"><span class="timeline-year">2015</span>
            <h4 class="timeline-title">Our nice super title</h4>
            <p class="timeline-text">Lorem ipsum dolor site amet, consectetur adipscing elit, sed do eisumod tempor incididut ut labore et dolore magna aliqua. Ut enim ad mimim venjam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
          </div>
        </div>
        <div class="swiper-slide" style="background-image: url(https://unsplash.it/1920/500?image=16" year="2016">
          <div class="swiper-slide-content"><span class="timeline-year">2016</span>
            <h4 class="timeline-title">Our nice super title</h4>
            <p class="timeline-text">Lorem ipsum dolor site amet, consectetur adipscing elit, sed do eisumod tempor incididut ut labore et dolore magna aliqua. Ut enim ad mimim venjam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
          </div>
        </div>
      </div>
      <div class="swiper-button-prev"></div>
      <div class="swiper-button-next"></div>
      <div class="swiper-pagination"></div>
    </div>
  </div>
</div>