kenwheeler / slick

the last carousel you'll ever need
kenwheeler.github.io/slick
MIT License
28.54k stars 5.89k forks source link

Can't prevent change of current slide #1138

Open adam-lynch opened 9 years ago

adam-lynch commented 9 years ago

I'd love to be able to prevent a user going to a certain steps until some conditions are met.

It's great that there are so many events but we need to be able to call e.preventDefault() or something like that. Or even if in a beforeChange callback you could overwrite the nextSlide slide passed in (for example: nextSlide = currentSlide). The closest I got was using slickGoTo inside a setPosition callback but then I realised this was causing an infinite loop and would require me to manage some slick state stuff outside of slick.

adam-lynch commented 9 years ago

Wait, it would all be so simple if I could just change slidesToScroll to 0. I've been playing around with the code. I think this would work fine except you do a lot of things like x / _.options.slidesToScroll or x % _.options.slidesToScroll and I'm not 100% sure what to do in each case.

adam-lynch commented 9 years ago

Ok, I've found a solution. If #1139 is merged, then I can use that along with disabling swipe temporarily. For example:

var $form = $('form');
  var allow = false;

  $form.on('beforeChange', function(e, slick, currentSlide){ 
    if(!allow){
      e.preventDefault(); 
    }
  });   

  $form.slick({
      slide = 'fieldset',
      dots: true,
      infinite: false,
      speed: 300,
      slidesToShow: 1,
      arrows: false,
      swipe: allow
  });

  // Just so it doesn't look like two dots are active
  $form.on('focus', '.slick-dots button', function(){
    $(this).trigger('blur');
  });

  $('#allow').on('click', function(e){
    allow = !allow;
    $form.slick('slickSetOption', 'swipe', allow, true);
  });

So with this, initially you cannot change slide (with click or swipe) and you can once #allow is clicked.

simeydotme commented 9 years ago

think about this logically....

Why would you want to prevent the slideChange when you've already triggered the slideChange? - it doesn't make sense.

If you want to prevent changing slides, then run the logic before you change slides and change the carousel options to disallow interaction... do not allow user to change slides and then stop half way through.

adam-lynch commented 9 years ago

If you want to prevent changing slides, then run the logic before you change slides and change the carousel options to disallow interaction

But I didn't see any way to disable / pause slick. The closest thing is unslick but that removes the dots and styling. I don't want to have to clone the dots manually or anything like that while it's "disabled".

adam-lynch commented 9 years ago

Ping

nfour commented 9 years ago

I also need this. It's necessary to have a way to intercept and trash events or else we have to build too much code around removing slick from varying input.

leggomuhgreggo commented 9 years ago

I had to do the same thing. This solution is hacked together, and I wouldn't rely on this being at all future proof, but here you go:

http://codepen.io/gwst/pen/gbVPpX

nfour commented 9 years ago

Heh, I ended up making my own slider module with a more flexible programmatic-friendly api. It probably took less time than trying to make slick work, having no need for some of the more advanced features (touch swiping, multiple items per slide). Kinda surprised at how easy it was.

Threw it up on nfour/slider. I feel like it does instantiated sliders well with that api, without repeating code. Perhaps slick could use an api like that.

simeydotme commented 9 years ago

Yep, creating sliders is super easy if you're doing it for your own situation with very few variables :) when your client starts asking for changes, features, crazy shit, though, that's when you come back to Slick aahahah ^^;

kenwheeler commented 9 years ago

So wait, you want slick to have a disabled state? I'm not sure I have anything set up for that, because I've never intentionally wanted to disable its functionality.

If a client came to me wanting this, I'd probably layer a div on top of slick that intercepted and killed events until my condition to enable slick was met. Not a core solution, but likely the simplest.

nfour commented 9 years ago

@kenwheeler that makes sense if the only input is from the user. Imagine if you were, for example, syncing a slider up with input from the server. That's what I've been running into.

kenwheeler commented 9 years ago

Oh so completely removing user control?

adam-lynch commented 9 years ago

Finally, a proper reply. Thanks @kenwheeler, it's appreciated :smile:.

I'd probably layer a div on top of slick that intercepted and killed events until my condition to enable slick was met.

(Assuming you mean using a transparent div with higher z-index...) Good idea but won't work for me. I've form elements in my slide elements that the user needs to be able to interact with. They'd need to fill in the fields (well, selects) before they can change slide (and we automatically change slides for them once they do too).

I know it's unusual to combine a form with a carousel but I don't think it's unreasonable though.

kenwheeler commented 9 years ago

You could modify the changeSlide method to check a global variable of your choice prior to committing to a slide change. I'd put it in core, but with the backlog and the time it takes to get it out to master and released, it might be longer than the time you have to do this in.

adam-lynch commented 9 years ago

@kenwheeler I think it should be done through Events. I'm willing to contribute. See my comment (and PR) above; https://github.com/kenwheeler/slick/issues/1138#issuecomment-79535135. We've been using my fork for awhile now.

EnigmaSolved commented 9 years ago

Similar to @adam-lynch I'm starting to explore using Slick for forms. I've been exploring plugins that are specifically oriented to working with multi-step forms (eg, jQuery Steps), but am having mixed results. Slick has been so solid in my other uses that I'm exploring using it for forms as well.

Based on my testing thus far it is not difficult to test for empty inputs in the current slide and then perform some kind of error notification (eg, apply error classnames to elements). But I too am having difficulty in preventing Slick from advancing to the next slide. I agree that Events make sense for where to handle this sort of thing. If we can add a way to prevent default behavior (eg, #1139) then I think we're golden. :)

adam-lynch commented 9 years ago

@EnigmaSolved maybe have a look at https://github.com/nolimits4web/Swiper/issues/1235. Haven't tried it yet myself.

EnigmaSolved commented 9 years ago

Thanks man! :) Currently I'm thinking that I want to either go with something like jQuery Steps that is specifically designed for working with forms (though I've run into some issues with that particular one, and it was my top choice of what I surveyed), or I want to work with Slick. Slick is such a great slider, I don't really feel motivated to add another slider to the mix (that isn't specifically for forms and thus offering form-specific benefits) if I can work with Slick. Thanks for the suggestion though!

dshamis317 commented 9 years ago

I've run into the same issue as @adam-lynch and @EnigmaSolved. Has there been any movement on something like this? Thanks everyone!

bgrayburn commented 9 years ago

+1 I'm essentially using the slide box to walk a user through various processes while still allowing them to jump around (under certain conditions). If these conditions aren't met I'll pop up a little alert and would like to gracefully deliver them from whence they came.

khalwat commented 9 years ago

+1. I need this too. I'm using slick to wrap a multi-part form, and would like to do validation before the user can move on to the next step.

much-rebel commented 9 years ago

+1. Trying to make magazine reader. In responsive mode when switching to one slide view - slide #0 (which in books normally is empty page) should be hidden, with initialSlide option it is possible to drop user to #1 slide, but still user can swipe back to #0 :(

vfonic commented 9 years ago

+1 I have a "shopping form steps" where I want to prevent user from proceeding to the next step if validation fails on current step.

cgdevelp commented 8 years ago

@leggomuhgreggo Perfect :+1: your code is almost similar to what i'm looking for. In a similar way to arrows i would like to control dots (pagination) as well based on some condition. Please let me know how can i do that similar to the way you wrote for arrows.

kinnaj commented 8 years ago

I´m not sure if you already solved this, but what I did for a multi-step form with slick slider (just wanted to see what I can do with it) I just created to new buttons which are disabled by default, if the user now fills out an input-field, a validator validates the input and if all inputs are validated, the user may click "next" and it goes to the next slide. On the last slide I check if all the previous inputs are valid (because the the content is in fact the html, just hidden) and then send it via ajax.

I also made a questionaire in that style with slick-slider. I misused ist alot and loved it for the flexibility :)

yinjinit commented 4 years ago

The only way to prevent it is to slide back the current to prev. This way: $slickSlider.on('afterChange', function(e, slick) { if ( LOGICAL CONDITION ) { slick.slickPrev(); } });