patrickkunka / mixitup

A high-performance, dependency-free library for animated filtering, sorting, insertion, removal and more
https://www.kunkalabs.com/mixitup/
4.52k stars 734 forks source link

Mix runs 4 times on page load. #604

Open robhuska opened 1 year ago

robhuska commented 1 year ago

As the title states, my MixItUp instance runs 4 times on page load. And since it does this the onMixEnd callback runs 4 times as well. I have a script to scroll the user back to the top of the page in my onMixEnd callback so on page load it scrolls to the filter section of my page, which is not ideal. I have to "hack" it by adding an iterator just to avoid the scroll on page load. Is there something. I may have done wrong?

Configuration

    var mixer = mixitup('#beer-loop',{
        load: {
            filter: '.on-tap'
        },
        multifilter: {
            enable: true,
            minSearchLength: 1,
            // keyupThrottleDuration: 0
        },
        controls: {
            toggleDefault: '.on-tap'
        },
        pagination: {
            limit: 12,
            hidePageListIfSinglePage: true,
        },
        templates: {
            pageStatsFail: 'Sorry there were no <span class="text-secondary">beers</span> found.',
        },
        callbacks: {
            onMixStart: function(state, futureState) {
                console.log(futureState.activeFilter.selector);
            },
            onMixEnd: function(state){
                if(pageLoad > 3) {
                    const yOffset = -45;
                    const mixTop = document.getElementById('nav-tab');
                    const y = mixTop.getBoundingClientRect().top + window.pageYOffset + yOffset;

                    window.scrollTo({top: y, behavior: 'smooth'});
                } else {
                    pageLoad++;
                }
            },
            onPaginateStart: function(state, futureState) {
            },
            onPaginateEnd: function(state, futureState) {
            }
        }
    });

Markup

I know there is a lot of markup but I didn't want to strip out too much so you could see all the filtering options I have... (It's a lot).

<main class="beers-archive">
  <section class="pb-5 bg-black text-white">
    <div class="container">
      <h1 class="visually-hidden"><?php the_title(); ?></h1>
      <div class="row pt-5">
        <div class="col-12">
          <nav class="pb-4">
            <div class="nav nav-tabs beers-archive__tabs" id="nav-tab" role="tablist" data-filter-group>
              <button class="btn active" data-filter=".on-tap" id="nav-on-tap-tab" data-bs-toggle="tab" data-bs-target="#nav-on-tap" type="button" role="tab" aria-controls="nav-on-tap" aria-selected="true">On Tap</button>
              <button class="btn" data-filter=".retail" id="nav-retail-tab" data-bs-toggle="tab" data-bs-target="#nav-retail" type="button" role="tab" aria-controls="nav-retail" aria-selected="false">Retail</button>
              <button class="btn" data-filter=".all" id="nav-all-beer-tab" data-bs-toggle="tab" data-bs-target="#nav-all-beer" type="button" role="tab" aria-controls="nav-all-beer" aria-selected="false">All Beer</button>
              <button class="btn" id="nav-search-tab" data-bs-toggle="tab" data-bs-target="#nav-search" type="button" role="tab" aria-controls="nav-search" aria-selected="false">Search</button>
            </div>
          </nav>
          <div class="tab-content beers-archive__content pb-5" id="nav-tabContent">
            <div class="tab-pane fade show active" id="nav-on-tap" role="tabpanel" aria-labelledby="nav-on-tap-tab" tabindex="0">
              <h2 class="text-uppercase">What's <span class="text-secondary">On Tap</span></h2>
              <?php echo wpautop(tr_field('on_tap_content')); ?>
            </div>
            <div class="tab-pane fade" id="nav-retail" role="tabpanel" aria-labelledby="nav-retail-tab" tabindex="0">
              <h2 class="text-uppercase">Retail</h2>
              <?php echo wpautop(tr_field('retail_content')); ?>
            </div>
            <div class="tab-pane fade" id="nav-all-beer" role="tabpanel" aria-labelledby="nav-all-beer-tab" tabindex="0">
              <h2 class="text-uppercase">All <span class="text-secondary">Beer</span></h2>
              <?php echo wpautop(tr_field('all_beer_content')); ?>
            </div>
            <div class="tab-pane fade" id="nav-search" role="tabpanel" aria-labelledby="nav-search-tab" tabindex="0">
              <h2 class="text-uppercase">Search <span class="text-secondary">Beer</span></h2>
              <fieldset data-filter-group="search" class="my-3">
                <input id="beer-search" class="beers-archive__search" type="search" data-search-attribute="data-search" placeholder="Search"/>
              </fieldset>
            </div>
          </div>
        </div>
      </div>

      <div class="row">
        <div class="col-12 col-md order-2">
          <div class="beers-archive__loop row" id="beer-loop">
            <?php $args = [
              'post_type' => 'beer',
              'numberposts' => -1,
              'orderby' => 'name',
              'order' => 'ASC',
            ];
            $beers = get_posts($args);
            $abvRange = ['min' => '1000', 'max' => '0'];
            $ibuRange = ['min' => '1000', 'max' => '0'];

            $all_types = get_terms(array(
              'taxonomy' => 'beer_type',
              'hide_empty' => true,
            ));

            $all_cats = get_terms(array(
              'taxonomy' => 'beer_category',
              'hide_empty' => true,
            ));

            if ($beers) { ?>
              <?php foreach ($beers as $beer) {
                $abv = tr_field('abv', $beer->ID);
                $ibu = tr_field('ibu', $beer->ID);
                $on_tap = tr_field('on_tap', $beer->ID);
                $bd_type = get_the_terms($beer->ID, 'beer_type');
                $bd_cats = get_the_terms($beer->ID, 'beer_category');
                $bd_series = get_the_terms($beer->ID, 'series');
                $bd_sold_in = get_the_terms($beer->ID, 'sold_in');

                $abvRange['min'] = $abv < $abvRange['min'] ? ($abv ? $abv : 0) : $abvRange['min'];
                $abvRange['max'] = $abv > $abvRange['max'] ? $abv : $abvRange['max'];
                $ibuRange['min'] = $ibu < $ibuRange['min'] ? ($ibu ? $ibu : 0) : $ibuRange['min'];
                $ibuRange['max'] = $ibu > $ibuRange['max'] ? $ibu : $ibuRange['max'];
              ?>
                <div style="display: none;" 
                  <?= $ibu ? 'data-ibu="' . $ibu . '"' : ''; ?>
                  <?= $abv ? 'data-abv="' . $abv . '"' : ''; ?>
                  class="beers-archive__beer mb-5 col-12 col-sm-6 col-lg-4 mix all <?= $on_tap ? ' on-tap' : ''; ?> <?= $bd_type ? implode(" ", wp_list_pluck($bd_type, 'slug')) : ''; ?> <?= $bd_cats ? implode(" ", wp_list_pluck($bd_cats, 'slug')) : ''; ?> <?= $bd_sold_in ? implode(" ", wp_list_pluck($bd_sold_in, 'slug')) : ''; ?>"
                  data-search="<?= strtolower(get_the_title($beer->ID)); ?> <?= $bd_type ? implode(" ", wp_list_pluck($bd_type, 'slug')) : ''; ?> <?= $bd_series ? implode(" ", wp_list_pluck($bd_series, 'slug')) : ''; ?>"
                >
                  <div class="beer-card card rounded-0">
                    <div class="beer-card__bg"></div>
                    <div class="card-body">
                      <?php if(has_post_thumbnail($beer->ID)) :
                        echo get_the_post_thumbnail( $beer->ID , 'medium_large');
                      endif; ?>
                    </div>
                    <div class="card-footer">
                      <h5 class="card-title text-uppercase text-primary display-5 mb-0"><?= get_the_title($beer->ID); ?></h5>
                      <p class="card-text fw-bolder fs-8 mb-2">
                        <?= $bd_type ? '<span class="text-uppercase d-block">' . implode(", ", wp_list_pluck($bd_type, 'name')) . '</span>' : '&nbsp;'; ?>
                      </p>
                      <p class="card-text fw-bolder fs-8 mb-4">
                        <?= $abv ? '<span class="d-block">ABV: ' . $abv . '%</span>' : ''; ?>
                        <?= $ibu ? '<span class="d-block">IBU: ' . $ibu . '</span>' : ''; ?>
                      </p>
                      <a href="<?= get_the_permalink($beer->ID); ?>" class="btn btn-primary text-white fs-8">Learn More</a>
                    </div>
                  </div>
                </div>
              <?php } ?>
            <?php } ?>
          </div>

          <hr />

          <div class="mixitup-page-controls">
            <div class="mixitup-page-list"></div>
            <div class="mixitup-page-stats"></div>
          </div>
        </div>

        <aside class="col-12 col-md beers-archive__filters pb-5">
          <a href="#beer-filters" class="beer-filters__toggle btn btn-sm btn-outline-primary text-white text-uppercase">Filter<i class="bi-filter ms-1 fs-6"></i></a>
          <div id="beer-filters" class="beer-filters">
            <div class="beer-filters__content">
              <fieldset>
                <div class="mb-4">
                  <label class="fs-7 fw-bolder text-uppercase mb-2">ABV Range</label>
                  <div id="abv-slider" data-min="<?= $abvRange['min']; ?>" data-max="<?= $abvRange['max']; ?>"></div>
                </div>

                <div class="mb-4">
                  <label class="fs-7 fw-bolder text-uppercase mb-2">IBU Range</label>
                  <div id="ibu-slider" data-min="<?= $ibuRange['min']; ?>" data-max="<?= $ibuRange['max']; ?>"></div>
                </div>
              </fieldset>

              <fieldset class="mb-4" data-filter-group>
                <label class="fs-7 fw-bolder text-uppercase mb-2">Type</label>

                <?php foreach ($all_types as $type) { ?>
                  <div class="form-check mb-1">
                    <input class="form-check-input" type="checkbox" name="type" value=".<?= $type->slug; ?>" id="<?= $type->slug; ?>">
                    <label class="form-check-label" for="<?= $type->slug; ?>">
                      <?= $type->name; ?>
                    </label>
                  </div>
                <?php } ?>
              </fieldset>

              <fieldset class="mb-4" data-filter-group>
                <label class="fs-7 fw-bolder text-uppercase mb-2">Category</label>

                <?php foreach ($all_cats as $cat) { ?>
                  <div class="form-check">
                    <input class="form-check-input" type="checkbox" name="cat" value=".<?= $cat->slug; ?>" id="<?= $cat->slug; ?>">
                    <label class="form-check-label" for="<?= $cat->slug; ?>">
                      <?= $cat->name; ?>
                    </label>
                  </div>
                <?php } ?>
              </fieldset>
            </div>
          </div>
        </aside>
      </div>
    </div>
  </section>
</main>

I am also using WordPress and Bootstrap and some of my filters are also buttons for controlling Bootstrap Tabs to show different text above the mix loop. There are a couple sets of checkboxes, a search field and a couple of range sliders. Though I am not sure why any of that would have any effect on MixItUp running 4 times on load.

Thanks, Rob