Jarek
Jarek

Reputation: 61

How to prevent slide change (navigating to another slide) in vue-slick-carousel?

I'm using vue-slick-carousel to load schedule data for given slide (which is a month in my case).

<vue-slick-carousel
  @afterChange="afterChange"
  @beforeChange="beforeChange"
  @swipe="swipe"
  class="text-center"
  :dots="true"
  :arrows="true"
  :initialSlide="getCurrentScheduleIndex"
  ref="mycarousel"
  v-if="this.schedules.length && !timeline_view"
>
  <template v-for="schedule in schedules">
    <div :key="schedule.id" class="schedule-slick-name">
      <em>{{ schedule.name }}</em>
    </div>
  </template>
</vue-slick-carousel>

If user make some changes in the schedule and accidentially clicks to change the slide I would like to warn user about unsaved changes and cancel carousel navigation. With native slick.js I was just invokig event.preventDefault() like below:

$('.mySlick').on('beforeChange', function(event, slick, currentSlide, nextSlide){
    
    if (unsaved){
       event.preventDefault();
     ...

But I have no idea how to do it in in vue. There is beforeChange event emitted as described in documentation but as I understand there is only currentSlide and nextSlide emitted.

beforeChange(currentSlide, nextSlide) {
      if (this.unsavedChanges) {
        if (
          this.confirmLeave(
            "Are you sure you want to leave? Unsaved changes will be lost."
          )
        ) {
          // Prevent from navigating to another slide like event.preventDefault();
        }
      } else {
        // Proceed with slide change ...
      }
      
    },

I was trying to use also another similar library vue-slick where there is an original jQuery event emitted but calling event.preventDefault() just not work:

beforeChange(event, slick, currentSlide, nextSlide) {
      if (this.unsavedChanges) {
        if (
          this.confirmLeave(
            "Are you sure you want to leave? Unsaved changes will be lost."
          )
        ) {
          // Prevent from navigatiing to another slide like event.preventDefault();
          event.preventDefault() // this does not work
        }
      } else {
        // Proceed with slide change ...
      }
      
    },

Maybe someone had the same problem? Thank you for any answer.

Upvotes: 0

Views: 2328

Answers (1)

Jarek
Jarek

Reputation: 61

I decided to modify vue-slick-carousel library by adding new prop (allowToSlideChange) which just simulate "cancel navigatiation" behavior:

If user does not cofirm that want's to change schedule month (change carousel slide) the cancelNavigation event is emitted instead of afterChange (where I invoke schedule load for selected month). I know that this is one of those ugly solutions but it works in my case pretty good :)

slideHandler(index, dontAnimate = false) {
  let navigate = true;
  const { asNavFor, speed } = this;
  // capture currentslide before state is updated
  const currentSlide = this.currentSlide;
  if (!this.allowToSlideChange) {
    navigate = window.confirm(this.slideChangeWarningMsg);
    if (!navigate) {
      index = currentSlide; // If user cancel navigation just set the same slide as before
    }
  }
...
navigate
      ? this.$parent.$emit("afterChange", state.currentSlide)
      : this.$parent.$emit("navigationCanceled", state.currentSlide);

Upvotes: 1

Related Questions