Isotope Combination Filters, Search and Sorts, messy and not complete

瘦欲@ 提交于 2019-12-08 11:20:33

问题


I have a page using Isotope. It combines a search box, multiple combination filters and finally some sorting options.

I have used many examples on the web to combine all this and stripped the code down as best I can (very limited isotope knowledge).

Two things -

Firstly, how can this be combined further? I currently have 3 separate 'sections' to the code.

Secondly, the search box works independent of the combination filters, and when the filters are clicked the search box stops working at all. is it possible to include the search in the filters so for example I can click two filters and type a word into the search and it will find anything that matches all three?

Here is all the code used that is relevant - Any help appreciated.

//Init Isotope and set sort options
$( function() {

var $filterDisplay = $('#filter-display');  

var $container = $('.results');
$container.isotope({
    filter: function() {
      return qsRegex ? $(this).text().match( qsRegex ) : true;
    },
    itemSelector: '.excerpt-home',
    masonry: {
    isFitWidth: true
    },
    getSortData: {
    name: '.name',
    price: function( itemElem ) {
    var price= $( itemElem ).find('.price-prop').text();
    return parseFloat( price.replace( /[\(\)]/g, '') );
    },
    distance: function( itemElem ) {
    var distance= $( itemElem ).find('.wppl-address').text();
    return parseFloat( distance.replace( /[\(\)]/g, '') );
    }
}
});
// sort items on button click
$('#sorts').on( 'click', 'button', function() {
  var sortByValue = $(this).attr('data-sort-by');
  $container.isotope({ sortBy: sortByValue });
});

// change is-checked class on buttons
  $('.button-group').each( function( i, buttonGroup ) {
    var $buttonGroup = $( buttonGroup );
    $buttonGroup.on( 'click', 'button', function() {
      $buttonGroup.find('.is-checked').removeClass('is-checked');
      $( this ).addClass('is-checked');
    });   
});  
});


var filters = {};
var qsRegex;

$(function(){

  $container = $('.results');
    // do stuff when checkbox change
  $('#options').on( 'change', function( jQEvent ) {
    var $checkbox = $( jQEvent.target );
    manageCheckbox( $checkbox );

    var comboFilter = getComboFilter( filters );

    $container.isotope({ filter: comboFilter });

    $filterDisplay.text( comboFilter );
  });

});

$( function() {
  // quick search regex


  // init Isotope
  var $container = $('.results').isotope({
    itemSelector: '.excerpt-home'

  });

  // use value of search field to filter
  var $quicksearch = $('#quicksearch').keyup( debounce( function() {
    qsRegex = new RegExp( $quicksearch.val(), 'gi' );
    $container.isotope();
  }, 200 ) );

});


// debounce so filtering doesn't happen every millisecond
function debounce( fn, threshold ) {
  var timeout;
  return function debounced() {
    if ( timeout ) {
      clearTimeout( timeout );
    }
    function delayed() {
      fn();
      timeout = null;
    }
    timeout = setTimeout( delayed, threshold || 100 );
  }
}



function getComboFilter( filters ) {
  var i = 0;
  var comboFilters = [];
  var message = [];

  for ( var prop in filters ) {
    message.push( filters[ prop ].join(' ') );
    var filterGroup = filters[ prop ];
    // skip to next filter group if it doesn't have any values
    if ( !filterGroup.length ) {
      continue;
    }
    if ( i === 0 ) {
      // copy to new array
      comboFilters = filterGroup.slice(0);
    } else {
      var filterSelectors = [];
      // copy to fresh array
      var groupCombo = comboFilters.slice(0); // [ A, B ]
      // merge filter Groups
      for (var k=0, len3 = filterGroup.length; k < len3; k++) {
        for (var j=0, len2 = groupCombo.length; j < len2; j++) {
          filterSelectors.push( groupCombo[j] + filterGroup[k] ); // [ 1, 2 ]
        }

      }
      // apply filter selectors to combo filters for next group
      comboFilters = filterSelectors;
    }
    i++;
  }

  var comboFilter = comboFilters.join(', ');
  return comboFilter;
}

function manageCheckbox( $checkbox ) {
  var checkbox = $checkbox[0];

  var group = $checkbox.parents('.option-set').attr('data-group');
  // create array for filter group, if not there yet
  var filterGroup = filters[ group ];
  if ( !filterGroup ) {
    filterGroup = filters[ group ] = [];
  }

  // index of
  var index = $.inArray( checkbox.value, filterGroup );

  if ( checkbox.checked ) {

    if ( index === -1 ) {
      // add filter to group
      filters[ group ].push( checkbox.value );
    }
  } else {
    // remove filter from group
    filters[ group ].splice( index, 1 );
  }

}

回答1:


I had the same problem and found the solution. The main thing to keep in mind is passing the data-attribute and the class as well, because the filter and search works as a filter function and the sorting has its own function.

Our project is to filter and sort all of the resorts by type, country, city, state. So I added classes for country, city, state, and state. For the category I added a resort type category to determine between luxury and regular resorts.

var qsRegex;
var buttonFilter;

// init Isotope var $container = $('.grid').isotope({ itemSelector: '.element-item', layoutMode: 'vertical', getSortData: { country: '.destination-country', state: '.destination-state', city: '.destination-city', resortType: '[data-resort-type]', typeR: '.destination-type-1', typeL: '.destination-type-2', typeAll: '.destination-type-all' }, filter: function() { var $this = $(this); var searchResult = qsRegex ? $this.text().match( qsRegex ) : true; var buttonResult = buttonFilter ? $this.is( buttonFilter ) : true; return searchResult && buttonResult; }, // sort top priority to lowest priority sortBy: ['resortType', 'country', 'state', 'city'] });

and here you can see how I can the isotope plugin.

// -------- Filter FUNCTION ----------//
$('.filter-by-button-group').on( 'click', 'button', function() {
    buttonFilter = $( this ).attr('data-filter-value');
    console.log("Filter button click",buttonFilter);
    $container.isotope();
});

// ----------- Search FUNCTION --------//
// use value of search field to filter
var $quicksearch = $('.quicksearch').keyup( debounce( function() {
    qsRegex = new RegExp( $quicksearch.val(), 'gi' );
    console.log("Search input",qsRegex);
    $container.isotope();
}) );

// ------------- Sort FUNCTION -------------//
// bind sort button click
$('.sort-by-button-group').on( 'click', 'button', function() {
    var sortValue = $(this).attr('data-sort-value');
    // make an array of values
    sortValue = sortValue.split(',');
    console.log("Sorting button click",sortValue);
    $container.isotope({ 
                sortBy: ['resortType', sortValue]
            });
});

and also have the debounce so the filtering doesn't happen every millisecond

// debounce so filtering doesn't happen every millisecond
function debounce( fn, threshold ) {
  var timeout;
  return function debounced() {
    if ( timeout ) {
      clearTimeout( timeout );
    }
    function delayed() {
      fn();
      timeout = null;
    }
    setTimeout( delayed, threshold || 100 );
  };
}

My HTML for each Item looks like this

                <!-- ----------------------------------start resort item --------------------------------------------------  -->
            <li class="destination-list element-item destination-type-all destination-type-1" data-resort-type="destination-type-all   destination-type-1">
                <div class="resort-details col-sm-2">
                    <div class="resortImage">
                        <img class="pull-left resort-img" src="./ResortListing_files/8804623745054.jpg" alt="Marriott&#39;s Canyon Villas" title="Marriott&#39;s Canyon Villas">
                    </div>

                    <div class="resortIcons col-md-12"> 
                        <span>
                            <i class="sr-only">Beach</i>
                            <img src="ResortListing_files/beach.png"/>
                        </span>
                        <span>
                            <i class="sr-only">Golf</i>
                            <img src="ResortListing_files/golf.png"/>
                        </span>
                        <span>
                            <i class="sr-only">Ski</i>
                            <img src="ResortListing_files/Ski.png"/>
                        </span>
                        <span>
                            <i class="sr-only">Theme Park</i>
                            <img src="ResortListing_files/theme_park.png"/>
                        </span>
                        <!--
                        <span>
                            <i class="sr-only">Urban</i>
                            <img src="ResortListing_files/urban.png"/>
                        </span>
                        -->
                    </div>
                </div>

                <div class="resort-details  col-md-7">
                    <a id="resortNameLink" href="https://st01.owners.marriottvacationclub.com/timeshare/mvco/exploredestination/resorts/resortoverview?resortId=CV" class="resort-name">
                        Marriott's Newport Coast<sup>&reg;</sup> Villas
                    </a>

                    <span class=" fa fa-star-o" style="color: #8B5F10 !important" data-target="#assocTModal" title="Marriott Vacation Regular Resort"></span>

                    <span class="association assoc-t" data-toggle="modal" data-target="#assocTModal" title="Marriott Vacation Club Trust Resort">
                    T
                    </span>
                    <span class="association assoc-e" data-toggle="modal" data-target="#assocEModal" title="Marriott Vacation Club Exchange Resort">
                    E
                    </span>


                    <div class="resortLocation">
                        <h2 class="destination-country">USA</h2>
                        <h4 class="destination-state">California</h4>
                        <h4 class="destination-city">Newport Coast</h4>
                    </div>

                    <p class="productdesc">Elegantly appointed and spacious villas accommodate up to 8 guests. Fitness center, two outdoor heated pools, whirlpool, plus separate children's pool. Sauna, sports court, putting green, and children's activity areas.</p>
                </div>

                <div class="resort-details actionButton col-md-2">
                    <!--<img src="http://cache.marriott.com/Images/MiniStores/Brand_Logos.png" />-->
                    <a href="#" class="resortBrandLogo cym">Court Yard Marriott</a>

                    <div class="resortListWeather transparent_class">
                        Weather: <strong>73.1°F</strong>
                        <img src="http://icons.wxug.com/i/c/k/cloudy.gif" alt="Sunny"/>
                    </div>

                    <a href="https://st01.owners.marriottvacationclub.com/timeshare/mvco/exploredestination/resorts/resortoverview?resortId=CV"  title="View Marriott's Canyon Villas Resort" class="btn viewResortBtn btn-default" target="_">
                        <span class="fa fa-arrow-circle-o-right" style="color: #8B5F10 !important" data-target="#assocTModal"></span> View This Resort
                    </a>
                </div>

                <div class="clearfix"></div>
            </li>
            <!--close resort item -->


来源:https://stackoverflow.com/questions/29481512/isotope-combination-filters-search-and-sorts-messy-and-not-complete

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!