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

Using Mixitup with multiple custom styled select dropdowns #600

Closed orcadesign closed 2 years ago

orcadesign commented 2 years ago

I'm using MixitUp with the multifilter extension to filter some of the room types in a site I'm developing. The CMS is WordPress so the general integration is easy and was working until introducing custom styled select dropdowns.

I've found a jQuery script that generates custom styled select dropdown lists - this leads me to my issue of having mixitup do it's thing when selecting an option from any of the dropdowns, as the jQuery replicates a div based version of the select menu it no longer works. Even when I try and console.log something I'm not getting anything through.

This is the template part to generate the is as follows:

<section class="relative bg-white-th lg:pb-16 pb-12">
    <div class="container lg:mb-24 xl:px-0 lg:px-4 px-8">
        <form action="" class="flex flex-row flex-wrap items-center">
            <div class="lg:w-1/3 w-1/2 lg:pr-4 pr-1 lg:mb-0 mb-8">
                <label for="people" class="uppercase lg:mb-4 opacity-40 lg:text-base text-sm">Book with us</label>
                <select name="people" id="No. of People" class="search-select custom-select" data-filter-group data-logic="and">
                    <option value="">No. of People</option>
                    <option value=".people-2">Up 1 People</option>
                    <option value=".people-2">Up 2 People</option>
                    <option value=".people-4">Up 3 People</option>
                    <option value=".people-4">Up 4 People</option>
                </select>
            </div>
            <div class="lg:w-1/3 w-1/2 lg:pr-2 pr-1 lg:mb-0 mb-8">
                <label for="price" class="uppercase lg:mb-4 opacity-40 lg:text-base text-sm">Price</label>
                <select name="price" id="Per Night" class="search-select custom-select" data-filter-group data-logic="and">
                    <option value="">Per Night</option>
                    <option value=".price-130">£130+ Per Night</option>
                    <option value=".price-140">£140+ Per Night</option>
                    <option value=".price-160">£160+ Per Night</option>
                    <option value=".price-180">£180+ Per Night</option>
                </select>
            </div>
            <div class="lg:w-1/3 w-1/2 lg:pl-2 pl-1 lg:mb-0 mb-8">
                <label for="features" class="uppercase lg:mb-4 opacity-40 lg:text-base text-sm">Features</label>
                <select name="features" id="Features" class="search-select custom-select" data-filter-group data-logic="and">
                    <option value="">Features</option>
                    <option value=".disabled">Disabled Access</option>
                    <option value=".dog-friendly">Dog Friendly</option>
                    <option value=".ground-floor">Ground Floor</option>
                    <option value=".interlink-door">Interlink Door</option>
                </select>
            </div>
        </form>     
    </div>
    <div class="container lg:px-0 px-8" id="filter-container">
        <?php
            while(have_rows('rooms')) : the_row();
            $post_object = get_sub_field('room');
            $post = $post_object; 
            setup_postdata( $post );
            $sleeps = get_field('sleeps');
            $from = get_field('from');
            $pets = get_field('pets');
            $description = get_field('description');
            $booking_link = get_field('booking_link');
            $location = get_field('location');
        ?>
        <div class="relative w-full lg:mb-16 mb-12 flex lg:flex-row flex-col mix price-<?php echo $from ?> people-<?php echo $sleeps ?>
        <?php while(have_rows('features_list')) : the_row();
            $features = get_sub_field('feature');
            $mod_name = strtolower(str_replace(' ', '-', $features));
        ;?> <?php echo $mod_name ?><?php endwhile;?>">
            <div class="lg:w-1/2 w-full relative search-image">
                <img src="<?php the_post_thumbnail_url(); ?>" alt="Thumbnail Image" class="absolute object-cover w-full h-full">
            </div>
            <div class="lg:w-1/2 w-full relative lg:p-8">
                <div class="w-full flex flex-row items-center justify-between mb-8">
                    <h4 class="text-3xl mb-2"><?php the_title(); ?></h4>
                    <svg class="accomo-fav" id="<?php the_ID(); ?>" width="22" height="21" viewBox="0 0 22 21" fill="none" xmlns="http://www.w3.org/2000/svg">
                        <path d="M15.5 1C13.76 1 12.09 1.81 11 3.09C9.91 1.81 8.24 1 6.5 1C3.42 1 1 3.42 1 6.5C1 10.28 4.4 13.36 9.55 18.04L11 19.35L12.45 18.03C17.6 13.36 21 10.28 21 6.5C21 3.42 18.58 1 15.5 1Z" stroke="black" stroke-width="2" stroke-linejoin="round"/>
                        <path d="M15.5 1C13.76 1 12.09 1.81 11 3.09C9.91 1.81 8.24 1 6.5 1C3.42 1 1 3.42 1 6.5C1 10.28 4.4 13.36 9.55 18.04L11 19.35L12.45 18.03C17.6 13.36 21 10.28 21 6.5C21 3.42 18.58 1 15.5 1Z" stroke="black" stroke-width="2" stroke-linejoin="round"/>
                    </svg>
                </div>              
                <p class="uppercase text-orange-th lg:mb-8"><?php echo $location ?></p>
                <p class="mb-2"><strong>Sleeps:</strong> Up to <?php echo $sleeps ?></p>
                <p class="mb-2"><strong>From:</strong> £<?php echo $from ?> per night</p>
                <p class="mb-8"><strong>Features:</strong>
                    <?php
                        $i = 0;
                        $count = count(get_sub_field('features_list'));
                        while(have_rows('features_list')) : the_row();
                            $i++;
                            $feature = get_sub_field('feature');
                    ?>  
                        <span><?php echo $feature ?>,</span>
                    <?php 
                        endwhile;
                    ?>
                </p>
                <p class="mb-8"><?php echo $description ?></p>
                <div class="w-full flex lg:flex-row flex-col">
                    <a href="<?php the_permalink(); ?>" class="btn-primary-transparent lg:w-auto w-full lg:mr-4 mr-0 lg:mb-0 mb-3">View Rooms</a>
                    <a href="hidden for privacy" target="_blank" class="btn-primary-transparent lg:w-auto w-full">Book Now</a>
                </div>
            </div>
        </div>
        <?php 
            wp_reset_postdata();
            endwhile; 
        ?>
    </div>
</section>  

This is the script for the MixitUp - it's located on the template part itself:

<script>
$(function(){

    var containerEl = document.querySelector('#filter-container');

    var mixer = mixitup(containerEl, {
        controls: {
            toggleLogic: 'and'
        },
        multifilter: {
            enable: true
        }
    });

    $('.custom-option').on('click', function() {
        var filterString = $('.selection').data('value')
        // var filterString = $(this).data('value') have also tried this as well to no avail
        console.log(filterString)
        mixer.filter(filterString);

    }); 

});
</script>

And this is the script that generates the custom select dropdowns:

  $(".custom-select").each(function() {
    var classes = $(this).attr("class"),
        id      = $(this).attr("id"),
        name    = $(this).attr("name");
    var template =  '<div class="' + classes + '">';
        template += '<span class="custom-select-trigger">' + $(this).attr('id') + '</span>';
        template += '<div class="custom-options">';
        $(this).find("option").each(function() {
          template += '<span class="custom-option ' + $(this).attr("class") + '" data-value="' + $(this).attr("value") + '">' + $(this).html() + '</span>';
        });
    template += '</div></div>';

    $(this).wrap('<div class="custom-select-wrapper"></div>');
    $(this).hide();
    $(this).after(template);
  });
  $(".custom-option:first-of-type").hover(function() {
    $(this).parents(".custom-options").addClass("option-hover");
  }, function() {
    $(this).parents(".custom-options").removeClass("option-hover");
  });
  $(".custom-select-trigger").on("click", function() {
    $('html').one('click',function() {
      $(".custom-select").removeClass("opened");
    });
    $(this).parents(".custom-select").toggleClass("opened");
    event.stopPropagation();
  });
  $(".custom-option").on("click", function() {
    $(this).parents(".custom-select-wrapper").find("select").val($(this).data("value"));
    $(this).parents(".custom-options").find(".custom-option").removeClass("selection");
    $(this).addClass("selection");
    $(this).parents(".custom-select").removeClass("opened");
    $(this).parents(".custom-select").find(".custom-select-trigger").text($(this).text());
  });

So currently when a .custom-option class is clicked on, nothing seems to happen, I've tried creating a single function to handle just logging a string message on click and it just seems to do nothing, once I can somehow pass this value across then I should be find to create the same mixer string that I used before to make the MixitUp section work. My only working theory is that I'm targeting the wrong selector - failing that because my jQuery for the MixitUp is within the template part it's getting loaded before and causing some sort of initialisation issue?