akiran / react-slick

React carousel component
http://react-slick.neostack.com/
MIT License
11.72k stars 2.1k forks source link

Slider broken when slides number are less than slidesToShow number specified. #1718

Open jgarmar opened 4 years ago

jgarmar commented 4 years ago

I created a sandbox to see the error (https://codesandbox.io/s/react-slick-playground-9o7gu), my problem is that if the number of slides is less than the specified one, the slider breaks, instead of showing me the items aligned to the left with the slider disabled, it duplicates them in the line below. Anyone can help me? thanks a lot.

Malin88 commented 4 years ago

You can just check if the number of slides are less ten declared in options. eg const slidesToShow = (this.props.slides.length < 3)? this.props.slides.length : 3;

madeFromCode commented 3 years ago

I added this to the start of the method that initializes the slider. It checks to see if the items being passed in to the slider is less than the max value for slides to show (we have different values for dynamic sizing). If the number of slides given is less than the number of slides to show then it concats another set of them to the array. This keeps the slides in order for infinite scrolling and gets around the bug.

const maxSlidesToShow = 6; if (slides.length > 0) { while (slides.length < maxSlidesToShow ) {
slides = slides.concat(slides) } }

ybogdanq commented 2 years ago

Guys you can use this code to generate new settings with "unslick" property for that media where slider breaks up (works only for responsive objects right now, but I'm sure you can modify it)

import { ResponsiveObject, Settings } from "react-slick";

const sliderItemsCountFix = (
  settings: Settings,
  itemsCount: number
): Settings => {
  if (!settings.responsive) return settings;
  const responsiveArray = settings.responsive.map((responsiveItem) => {
    const responsive: Settings | false =
      responsiveItem.settings !== "unslick" && responsiveItem.settings;
    if (!responsive) return;
    const slidesToShow: number = responsive.slidesToShow || 1;
    const isItemsMoreThanSlidesToShow = itemsCount > slidesToShow;

    return isItemsMoreThanSlidesToShow
      ? responsiveItem
      : ({ ...responsiveItem, settings: "unslick" } as ResponsiveObject);
  });

  return { ...settings, responsive: responsiveArray } as Settings;
};

export default sliderItemsCountFix;

Just use "sliderItemsCountFix" function whenever you need to fix the problem with slider. You can apply it like this:

<Slider
    {...sliderItemsCountFix(sliderSettings, items.length)}
 ></Slider>

"sliderSettings" is your settings/configuration object for slider "items.length" in this case the amount or rendered slides

darkmantle commented 2 years ago

None of these are really fixes, and it means we can't have a slider of 4 with only 2 items in. Is there any way to do that?

rhfarukh commented 1 year ago

Bro, I think this approach is better as I solved this like below steps:

  1. Lets we have slick slide with 6 items. So we should have total 7 items so that the Slick Slide will work.
  2. So I checked first if the Array has items less than 7 then I returned bootstrap row and column grid with loop like
    ....looping
    ......As I like to view 6 items in a row so col-log2 col-md ....as your decision.
  3. then I used else and called the Slick Slider... See the Example Below..

My sample Code:

{ recommendedListItems && recommendedListItems.length < 7 ? <>

{ recommendedListItems?.map((item, index) => { let image_path = item?.productVariation?.[0]?.productVariationImage?.[0]?.image_path || null; return (
                                );
                            })
                        }
                    </div>
                </>
                :
                <>
                    <div className="recommended-list nav-at-top-right">
                        <Slider {...settings}>
                            {
                                recommendedListItems &&
                                recommendedListItems?.map((item, index) => {
                                    let image_path = item?.productVariation?.[0]?.productVariationImage?.[0]?.image_path || null;

                                    return (
                                        <BasicProductTile className="item" key={item?.id || index}
                                            title={item?.productDetail?.[0]?.name || ""}
                                            image={image_path ? `${BASE_URL}/${image_path}` : ""}
                                            price={displayProductPrice(item?.productVariation?.[0]) || ""}
                                            cutdownPrice={displayProductCutdownPrice(item?.productVariation?.[0]) || ""}
                                            productTags={item?.productTags || null}
                                            link={`/product-details/${item?.id || ""}`}
                                        />
                                    );
                                })
                            }
                        </Slider>
                    </div>
                </>
        }
rhfarukh commented 1 year ago

It is Actually Like : If Array Item has less than 7 items we are returning Bootstrap row with column loop..to view the 6 items Else

whynotadv commented 1 year ago

I need help with this issue too. Perhaps it's more of a PHP question but for some reason I cannot figure out why the Slick Slider doesn't disable when there are less than 4 posts being shown in my case. I need to revise the following code so that it looks to see if any communities show less than 4 related floor plans to disable the slick slider? Not sure how to handle this....Here's my code, any help would be super-appreciated.

my code.txt

whynotadv commented 1 year ago

I fixed my own silly issue, I neglected to include the closing

tag as: echo '</div>'; once I did that on line 42 before the else: print statement in my code.txt file I previously shared. Why is it always the simple stuff that breaks an entire product lol?

MRUNAL727 commented 10 months ago

This happens when you have less images than you have declared slides to show. Change your settings to var settings = { dots: true, slidesToShow: 5, infinite: false };