Search code examples
javascriptjquerymixitup

How to apply reset button only to each select instead of all filtering options in Mixitup?


Here's my code: http://codepen.io/kikibres/pen/mVYOaR

I’m trying to recode the select options to display the “X” button when it’s selected and when one click on the “X” button, it reset back to the original select value. Additionally, I wanted the "x" button to work only on their own dropdown menu instead of all dropdown menus.

I’m trying to make it more similar to http://www.mtommaneycentre.com.au/stores/. As you can see, when you click on an option in “A-Z” select field, an “X” button appears and when you click on the “X” button, it reset to the original “A-Z” select option….

How do one do that?

HTML

<div class="filtermenu">
<form class="controls" id="Filters">

  <fieldset class="select-style">

    <select>
      <option value="">All</option>
      <option value=".triangle">Triangle</option>
      <option value=".square">Square</option>
      <option value=".circle">Circle</option>
    </select>
    <button class="btn-clear">x</button>
  </fieldset>

  <fieldset class="select-style">

    <select>
      <option value="">All</option>
      <option value=".blue">Blue</option>
      <option value=".white">White</option>
      <option value=".green">Green</option>
    </select>
    <button class="btn-clear">x</button>
  </fieldset>


    <fieldset>
  <button class="filter" data-filter=".triangle">Triangle</button>
  </fieldset>

  <fieldset>
    <input type="text" placeholder="Enter Name" val="" data-filter="" id="filter--text" />
  </fieldset>

  <button id="Reset">Clear Filters</button>
</form>
</div>

Javascript The code that reset all options is

self.$reset.on('click', function(e){ e.preventDefault();

in

var dropdownFilter = {

  // Declare any variables we will need as properties of the object

  $filters: null,
  $reset: null,
  groups: [],
  outputArray: [],
  outputString: '',

  // The "init" method will run on document ready and cache any jQuery objects we will need.

  init: function(){
    var self = this; // As a best practice, in each method we will asign "this" to the variable "self" so that it remains scope-agnostic. We will use it to refer to the parent "dropdownFilter" object so that we can share methods and properties between all parts of the object.

    self.$filters = $('#Filters');
    self.$reset = $('#Reset');
    self.$container = $('#Container');

    self.$filters.find('fieldset').each(function(){
      var $this = $(this);

      self.groups.push({
        $buttons : $this.find('.filter'),
                $inputsSelect : $this.find('select'),
                $inputsText : $this.find('input[type="text"]'),
                active : ''
            });
        });

    self.bindHandlers();
  },


  // The "bindHandlers" method will listen for whenever a select is changed. 

  bindHandlers: function(){
    var self = this;

    // Handle select change

 self.$filters.on('click', '.filter', function(e){
      e.preventDefault();

      var $button = $(this);

      // If the button is active, remove the active class, else make active and deactivate others.

      $button.hasClass('active') ?
        $button.removeClass('active') :
        $button.addClass('active').siblings('.filter').removeClass('active');

      self.parseFilters();
    });

    // Handle dropdown change

    self.$filters.on('change', function(){
      self.parseFilters();           
    });

     // Handle key up on inputs
        self.$filters.on('keyup', 'input[type="text"]', function() {

            var $input = $(this);
            console.log($input.val());            
            $input.attr('data-filter', '[class*="'+$input.val().replace(/ /, '-')+'"]');
            if ($input.val() == '')
              $input.attr('data-filter', '');
            console.log($input.attr('data-filter'));
            self.parseFilters();

        });

    // Handle reset click

    self.$reset.on('click', function(e){
      e.preventDefault();

      self.$filters.find('.filter').removeClass('active');
      self.$filters.find('.show-all').addClass('active');
      self.$filters.find('select').val('');

self.$filters.find('input[type="text"]').val('').attr('data-filter', '');

      self.parseFilters();
    });
  },

  // The parseFilters method pulls the value of each active select option

  parseFilters: function(){
    var self = this;

    // loop through each filter group and grap the value from each one.

    for(var i = 0, group; group = self.groups[i]; i++){

          var activeButtons = group.$buttons.length ? group.$buttons.filter('.active').attr('data-filter') || '' : '';            
          var activeSelect = group.$inputsSelect.length ? group.$inputsSelect.val()  || '' : '';
          var activeText = group.$inputsText.length ? group.$inputsText.attr('data-filter') : ''; 

          group.active = activeButtons+activeSelect+activeText;

          console.log(group.active);
        } 

        self.concatenate();

    },

  // The "concatenate" method will crawl through each group, concatenating filters as desired:

  concatenate: function(){
    var self = this;

    self.outputString = ''; // Reset output string

    for(var i = 0, group; group = self.groups[i]; i++){
      self.outputString += group.active;
    }

    // If the output string is empty, show all rather than none:

    !self.outputString.length && (self.outputString = 'all'); 

    console.log(self.outputString); 

    // ^ we can check the console here to take a look at the filter string that is produced

    // Send the output string to MixItUp via the 'filter' method:

      if(self.$container.mixItUp('isLoaded')){
        self.$container.mixItUp('filter', self.outputString);
      }
  }
};

// On document ready, initialise our code.

$(function(){

  // Initialize dropdownFilter code

  dropdownFilter.init();

  // Instantiate MixItUp

  $('#Container').mixItUp({
    controls: {
      enable: false // we won't be needing these
    },
    callbacks: {
      onMixFail: function(){
        alert('No items were found matching the selected filters.');
      }
    }
  });    
});

Solution

  • At the moment there isn't attached any event handler to your "x" buttons, so if you click on them, it just refreshes the page, that's why it resets all filters, because it reinitialize all the code.

    You should add this code to your plugin

    $('.btn-clear').on('click', function(event) {
        event.preventDefault();
        $(this).prev().val("").change();
    });
    

    The event.preventDefault() will prevent to run the default event when you click on the button, which is to refresh the page in this case.

    The next line will points to the previous DOM element of the clicked element (which is the <select>) and changes to the option which has the value: "", and after it triggers a change() event to tell your written code that the select's value is changed, so it should reload the figures with new filters.

    I saved it here: http://codepen.io/anon/pen/EPzWEQ?editors=1010 Of Course you should implement it to your plugin, I just wrote it to the bottom of the code to make it work.

    EDIT: If you want to make invisible the X buttons if there is no filter selected, just make a 'change' event handler on the select, and check if value is "" then hide the button, else show it. It should be look like this:

    $('select').change(function() {
        if ($(this).val() == "") { 
            $(this).next().hide();
        } else { 
            $(this).next().show();
        } 
    });