glide icon indicating copy to clipboard operation
glide copied to clipboard

disabledArrow: CSS Class .glide__arrow--disabled is not set

Open dmitrybret opened this issue 6 years ago • 16 comments

For Type: slider in case rewind: false disabledArrow (.glide__arrow--disabled) should be set.

Thanx a lot

dmitrybret avatar Jan 04 '19 14:01 dmitrybret

I have the same problem.

rikjacobs1390 avatar Jan 28 '19 12:01 rikjacobs1390

Would be a great addition

petervangennip avatar Jan 29 '19 08:01 petervangennip

Same problem

nflorentin avatar Feb 22 '19 11:02 nflorentin

Any update on this? Looks like a deal-breaker.

RomkaLTU avatar Feb 27 '19 22:02 RomkaLTU

Hey, i created a PR for this. Take a look at #328

omares avatar Mar 19 '19 16:03 omares

For anyone stumbling over this problem before the PR is merged and the version 3.4.0 is relased:

I wrote a small helper Component, that adds a disabled attribute to the prev/next buttons on the first/last slide.

var ArrowDisabler = function (Glide, Components, Events) {
  return {
    mount() {
      // Only in effect when rewinding is disabled
      if (Glide.settings.rewind) {
        return
      }
      
      Glide.on(['mount.after', 'run'], () => {
        // Filter out arrows_control
        for (let controlItem of Components.Controls.items) {
          if (controlItem.className !== 'glide__arrows') {
            continue
          }

          // Set left arrow state
          var left = controlItem.querySelector('.glide__arrow--left')
          if (left) {
            if (Glide.index === 0) {
              left.setAttribute('disabled', '') // Disable on first slide
            } else {
              left.removeAttribute('disabled') // Enable on other slides
            }
          }

          // Set right arrow state
          var right = controlItem.querySelector('.glide__arrow--right')
          if (right) {
              if (Glide.index === Components.Sizes.length - Glide.settings.perView) {
                right.setAttribute('disabled', '') // Disable on last slide
              } else {
                right.removeAttribute('disabled') // Disable on other slides
              }
          }
        }
      })
    }
  }
}

Use it like

new Gilde('.glide').mount({ ArrowDisabler })

bennol avatar Jun 14 '19 09:06 bennol

@bennol This was super useful, I hope this was a part of the library as it's a pretty common usecase. A few things in your code, that I tinkered to make it work are:

  1. The classes glide__arrow--right, .glide__arrow--left, 'glide__arrows' doesn't gets added automatically as of v3.3.0. This are not in the documentation anymore: https://glidejs.com/docs/options/#classes & the one with disabledArrow is defined but not being used in the codebase. https://github.com/glidejs/glide/search?q=disabledArrow&unscoped_q=disabledArrow

So the one who is using can replace those with their own custom classes, whatever they might have put on those elements.

  1. When bound is true, this mayn't work, we'll need to add in perView to get the calculation of next arrow right.

Here's the final code I'll be using:

// Modify these according to your controls
const classes = {
  'controls': 'slider-controls',
  'backArrow': 'slider-back',
  'nextArrow': 'slider-next',
};

function ArrowDisabler (Glide, Components) {
  return {
    mount() {
      // Only in effect when rewinding is disabled
      if (Glide.settings.rewind) {
        return
      }

      Glide.on(['mount.after', 'run'], () => {
        // Filter out arrows_control
        for (let controlItem of Components.Controls.items) {
          if (controlItem.className !== classes.controls) {
            continue
          }

          // Set left arrow state
          var left = controlItem.querySelector('.' + classes.backArrow)
          if (left) {
            if (Glide.index === 0) {
              left.setAttribute('disabled', '') // Disable on first slide
            } else {
              left.removeAttribute('disabled') // Enable on other slides
            }
          }

          // Set right arrow state
          var right = controlItem.querySelector('.' + classes.nextArrow)
          if (right) {
            // Glide.index is based on the active slide
            // For bound: true, there will be no empty space & the last slide will never become active
            // Hence add perView to correctly calculate the last slide
            const lastSlideIndex = Glide.settings.bound
              ? Glide.index + (Glide.settings.perView - 1)
              : Glide.index;

            if (lastSlideIndex === Components.Sizes.length - 1) {
              right.setAttribute('disabled', '') // Disable on last slide
            } else {
              right.removeAttribute('disabled') // Disable on other slides
            }
          }
        }
      })
    }
  }
}

export default ArrowDisabler;

Usage like you mentioned:

new Gilde('.glide').mount({ ArrowDisabler })

PezCoder avatar Jun 17 '19 15:06 PezCoder

Hi guys, I am not 100% sure but shouldn't be Components.Sizes.length - 1 changed to Components.Sizes.length - Glide.settings.perView ?

jaahoo avatar Jul 22 '19 19:07 jaahoo

@omares ~~I saw that your PR has been merged. But how come the class is still not applied?~~

I just dive into the source code, the PR that has been merged was not included in the latest version.

praburangki avatar Oct 19 '19 09:10 praburangki

Agree, the problem is still there.

ivarzLV avatar Oct 22 '19 18:10 ivarzLV

Any updates here? It would be great to have this available in the package.

guilhermeocosta avatar Mar 06 '20 18:03 guilhermeocosta

Same problem here

guillaumew avatar Mar 20 '20 09:03 guillaumew

I'm not seeing any disabled class being passed to the first button initially when there is no ability to go back. Is the solution for the now involve a custom helper (as above) to make this work?

mpukit avatar Jun 03 '20 18:06 mpukit

Bump on this one. This really should be part of the base controls package.

jripmeester avatar Sep 16 '20 08:09 jripmeester

Agreed. This really needs to be implemented.

a1402980 avatar Oct 07 '20 12:10 a1402980

For those who want to also hide any extra bullets that, when clicked, bring in whitespace (bullets are not restricted by the bound option), I followed @PezCoder 's approach and this works nicely along with his. It requires that {bound: true, focusAt: 0}, although that check may not be 100% necessary. Hope it helps someone.

function SlidelessDotDisabler(Glide, Components) {
    return {
        mount() {
            if (Glide.settings.bound && Glide.settings.focusAt === 0) {
                Glide.on(['mount.after', 'run'], function() {
                    for (let controlItem of Components.Controls.items) {
                        if (controlItem.className !== 'glide__bullets') {
                            continue
                        }
                        var slideCount = Components.Html.slides.length;
                        var visibleSlides = Glide.settings.perView;
                        var dotsToShow = slideCount - (visibleSlides - 1);
                        var dots = controlItem.querySelectorAll('.glide__bullet');
                        if (dots) {
                            for (var i = 0; i < dots.length; i++) {
                                if (i > (dotsToShow - 1)) {
                                    dots[i].remove();
                                }
                            }
                        }
                    }
                })
            }
        }
    }
};

peterdarthur avatar Jul 28 '21 08:07 peterdarthur