Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto populate bullets #241

Closed
projodesign opened this issue Jul 15, 2018 · 14 comments
Closed

Auto populate bullets #241

projodesign opened this issue Jul 15, 2018 · 14 comments

Comments

@projodesign
Copy link

Assume there is a reason that the bullets have to be hard coded, rather than generated based on how many slides there are? Planning to use with a CMS where slides could be added or removed by a user. Fairly simple to implement my end, just wondered if you'd considered building it in?

@garygreen
Copy link

garygreen commented Jul 28, 2018

I'm new to Glide so wondered about this too. Would it be difficult to use dots and responsive based sliders, as the number of dots would change if your showing less per view? I assume at the moment you would have to do some manual changes of the DOM to accommodate this?

As an alternative, I'm wondering if maybe you could use some CSS responsive utility classes (in this case Tailwind and using Blade php) and then wire up your Glide instance to match the same breakpoints?

<!-- Showing 1 per view by default -->
<div class="glide__bullets md:hidden" data-glide-el="controls[nav]">
  @foreach (range(0, $pictures->count()) as $i)
    <button class="glide__bullet" data-glide-dir="={{ $i }}"></button>
  @endforeach
</div>

<!-- Showing 3 per view on medium screens and up -->
<div class="glide__bullets hidden md:block" data-glide-el="controls[nav]">
   @foreach (range(0, ceil($pictures->count() / 3)) as $i)
    <button class="glide__bullet" data-glide-dir="={{ $i }}"></button>
  @endforeach
</div>

@elchiconube
Copy link

I'm also interested, right now I'm not available to use bullets because they doesn't builded dynamically and I cannot hardcoded every time. Please consider implement it

@rishabh2712
Copy link

+1

@garygreen garygreen mentioned this issue Mar 13, 2019
1 task
@ebrahimpleite
Copy link

ebrahimpleite commented Nov 10, 2019

someone did?

@dukeatcoding
Copy link

dukeatcoding commented Nov 27, 2019

Tried to implement a similiar solution for Angular 8 - also sturggeling to generate bullets.

But sadly it does not work

 <div class="glide__bullets" data-glide-el="controls[nav]">
      <div *ngFor="let bullet of bullets">
              <button class="glide__bullet" data-glide-dir="={{bullet.dir}}"></button> 
          </div>
 </div>  

@gaetanvdberge
Copy link

gaetanvdberge commented Mar 19, 2020

I also needed the bullets to be dynamically generated. I counted the amount of items and added the bullets dynamically before I mount glide.js.

function generateBulletsAndMountGlide() {
	var bulletCount = document.querySelectorAll('#carousel .glide__slide').length;
	var bulletWrapper = document.getElementById('glide__bullets');

	for (let index = 0; index < bulletCount; index++) {
		const button = document.createElement('button');
		button.className = 'glide__bullet';
		button.setAttribute("data-glide-dir", '='+index);

		bulletWrapper.appendChild(button)
	}

	glide.mount();
}

@cadday
Copy link

cadday commented Jul 10, 2020

I have just modified @gaetanvdberge 's solution. It creates bullets and checks if they need to be shown based on the breakpoint.

// myGlide is a regular glide instance and d-none is a simple css class thats sets display:none;
// Appending max number of dots
myGlide.on(['mount.before'], function () {
  const bulletCount = myGlide.settings.perView;
  const bulletWrapper = myGlide.selector.querySelectorAll('.glide__bullets')[0];
  for (let index = 0; index < bulletCount; index++) {
    const button = document.createElement('button');
    button.className = 'glide__bullet';
    button.setAttribute("data-glide-dir", '=' + index);
    bulletWrapper.appendChild(button);
  }
});

// Hiding them with d-none if it is needed
myGlide.on(['resize', 'build.after'], function () {
  const perView = myGlide.settings.perView;
  const total = myGlide.selector.querySelectorAll('.glide__slide').length;
  const sub = total - perView;
  // Adds or removes d-none class
  myGlide.selector.querySelectorAll('.glide__bullet').forEach((el, i) => {
    if (i > sub) {
      el.classList.add("d-none");
    } else {
      el.classList.remove("d-none");
    }
  });

  // Prevents the empty last stop when resized for a larger breakpoint with more items
  if (myGlide.index > sub) {
    myGlide.go('=' + sub);
  }
});

myGlide.mount().update();

@protherj
Copy link

protherj commented Jan 8, 2021

This isn't quite correct. The perView isn't the # of bullets, but rather "total slides" / perView.

The problem I'm having is that the bullets automatically are set to "active" by glide js incorrectly. It is using the button number correlated to the slide number, but not the "view" number.

I'll post code if I can get it working

@shestakov-vladyslav
Copy link

shestakov-vladyslav commented Apr 9, 2021

+++

@davidlower8
Copy link

davidlower8 commented May 20, 2021

I thought I'd leave this code snippet for anyone trying to get this to work with wordpress/php.

<?php $testimonial_query = new WP_Query($args); ?>
<div class="glide__bullets" data-glide-el="controls[nav]">
    <?php $testimonial_count = 0; ?>
    <?php while ($testimonial_query->have_posts()) : $testimonial_query->the_post(); ?>
         <button class="glide__bullet" data-glide-dir="=<?php echo $testimonial_count ?>"></button>
         <?php $testimonial_count++ ?>
    <?php endwhile; ?>
</div>

@rinart73
Copy link

I made changes in the Control component.

mount () {
  /**
   * Collection of navigation HTML elements.
   *
   * @private
   * @type {HTMLCollection}
   */
  this._n = Components.Html.root.querySelectorAll(NAV_SELECTOR)
  
  //Automatically create bullets
  const bulletWrapper = Components.Html.root.querySelector('.glide__bullets');
  if(bulletWrapper) {
    const fragment = document.createDocumentFragment();
    for(var index = 0; index < Components.Html.slides.length; index++) {
      var button = document.createElement('button');
      button.className = 'glide__bullet';
      button.setAttribute("data-glide-dir", '=' + index);
      fragment.appendChild(button);
    }
    bulletWrapper.innerHTML = '';
    bulletWrapper.appendChild(fragment);
  }

  /**
   * Collection of controls HTML elements.
   *
   * @private
   * @type {HTMLCollection}
   */
  this._c = Components.Html.root.querySelectorAll(CONTROLS_SELECTOR)

  this.addBindings()
},

I'm using bulletWrapper.innerHTML = '' to clear an optional placeholder bullet that could be used to prevent layout shift.
As a result my bullets HTML is:

<div class="glide__bullets" data-glide-el="controls[nav]">
    <button class="glide__bullet"></button>
</div>

@andyjamesn
Copy link

andyjamesn commented Oct 7, 2021

I was able to get this working by extending the component as follows.

@rinart73's code is spot on but instead of modifying the code its reworked to extend the Controls component as follows

const autoBullets = function (Glide, Components, Events) {
    return {
        mount() {
            var NAV_SELECTOR = '[data-glide-el="controls[nav]"]';
            var CONTROLS_SELECTOR = '[data-glide-el^="controls"]';
            
            this._n =
                Components.Html.root.querySelectorAll(NAV_SELECTOR);

            //Automatically create bullets
            const totalSlides = Components.Html.slides.length;
            const bulletWrapper =
                Components.Html.root.querySelector(NAV_SELECTOR);
            if (bulletWrapper) {
                const fragment = document.createDocumentFragment();
                for (var index = 0; index < totalSlides; index++) {
                    var button = document.createElement('button');
                    button.className = 'glide__bullet';
                    button.setAttribute('data-glide-dir', '=' + index);
                    fragment.appendChild(button);
                }
                bulletWrapper.innerHTML = '';
                bulletWrapper.appendChild(fragment);
            }

            this._c =
                Components.Html.root.querySelectorAll(
                    CONTROLS_SELECTOR
                );

            Components.Controls.addBindings();
        }
    };
};
new Glide(this.DOM.el).mount({
    AutoBullets: autoBullets
});

@jedrzejchalubek
Copy link
Member

Bullets auto-population will not be a part of the core of Glide. The way I can recomend is something proposed by @andyjamesn. You just need to mound your own extension.

@bastian-hidalgo
Copy link

bastian-hidalgo commented Jul 25, 2022

Bullets auto-population will not be a part of the core of Glide. The way I can recomend is something proposed by @andyjamesn. You just need to mound your own extension.

Theres no sense to implement an extension for a basic "slider/carousel" behavior

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests