tiffsaw tiffsaw - 2 months ago 6
Javascript Question

JQuery sort and filter list

I'm running into an issue where I'm unable to filter if I previously selected a sort value. I only want to sort the visible items but when I select a different filter option, the filter doesn't update. Any suggestions would be greatly appreciated. thank you so much

here's my js:

// Filtering plans options
$('.js-filter-options li a').click(function() {

// looks for the class of the clicked options
var allPlans = $(this).attr('class');
// reset the active class on all the options
$('.js-filter-options li, .js-input-check').removeClass('active');
// update the active state on clicked option
$(this).parent().addClass('active');
$(this).children().toggleClass('active');

if(allPlans == 'js-all-plans') {
// show all the plans
$('.js-filter-results').find('section.js-filter-results-plans').show();
}
else {
// hide plans that don't match class
$('.js-filter-results').find('section:not(.' + allPlans + ')').hide();
// show plans that are match class
$('.js-filter-results').find('section.' + allPlans).show();
}
});//end

//Dropdown options filtering
$('.js-dropdown-filter').change(function() {
var $filterList = $('.js-filter-results-plans:visible');

// Do something for option price lowest to highest
if ($(this).val() === 'low-high') {
var lowHigh = $filterList.sort(function (a, b) {
return $(a).find('.price__amount').text() > $(b).find('.price__amount').text();
});
$('.js-filter-results').html(lowHigh);

}
// Do something for option price highest to lowest
else if ($(this).val() === 'high-low') {
var highLow = $filterList.sort(function (a, b) {
return $(a).find('.price__amount').text() < $(b).find('.price__amount').text();
});
$('.js-filter-results').html(highLow);
}
// Do something for option popular
else {
var popular = $filterList.sort(function (a, b) {
return $(a).data("order")-$(b).data("order");
});
$('.js-filter-results').html(popular);
}
});//end


FIDDLE: https://fiddle.jshell.net/tLLfkg5w/

MJH MJH
Answer

Unless I am still misunderstanding you, the problem seems to be this line:

var $filterList = $('.js-filter-results-plans:visible');


When your "1" or "2" filter is applied, :visible ensures that $filterList starts out containing only two elements, when I believe you want it to contain all four of the elements. So, in the snippet below, I removed :visible:

var $filterList = $('.js-filter-results-plans');


UPDATE: I was going to mention parseInt, but you beat me to it. Apart from that, the improper sorting is not caused by the lack of :visible, it's caused by the fact that the return lines in your numerical sorts are incorrect. See the modified snippet below. Again, please let me know if the snippet gives the desired behavior.

// Filtering plans options 
$('.js-filter-options li a').click(function() {

    // looks for the class of the clicked options
    var allPlans = $(this).attr('class');
    // reset the active class on all the options
    $('.js-filter-options li, .js-input-check').removeClass('active');
    // update the active state on clicked option
    $(this).parent().addClass('active');
    $(this).children().toggleClass('active');
    
    if(allPlans == 'js-all-plans') {
        // show all the plans
        $('.js-filter-results').find('section.js-filter-results-plans').show(); 
    }
    else {
        // hide plans that don't match class
        $('.js-filter-results').find('section:not(.' + allPlans + ')').hide();
        // show plans that are match class
        $('.js-filter-results').find('section.' + allPlans).show();
    }
});//end

//Dropdown options filtering
$('.js-dropdown-filter').change(function() {
    // var $filterList = $('.js-filter-results-plans:visible');
    var $filterList = $('.js-filter-results-plans'); 

    // Do something for option price lowest to highest
    if ($(this).val() === 'low-high') {
        var lowHigh = $filterList.sort(function (a, b) {
            return parseInt($(a).find('.price__amount').text()) - parseInt($(b).find('.price__amount').text());
        });
        $('.js-filter-results').html(lowHigh);

    }
    // Do something for option price highest to lowest
    else if ($(this).val() === 'high-low') {
        var highLow = $filterList.sort(function (a, b) {
            return parseInt($(b).find('.price__amount').text()) - parseInt($(a).find('.price__amount').text());
        });
        $('.js-filter-results').html(highLow);
    }
    // Do something for option popular
    else {
        var popular = $filterList.sort(function (a, b) {
            return $(a).data("order")-$(b).data("order");
        });
        $('.js-filter-results').html(popular);  
    }
});//end
.h-hidden {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<ul class="js-filter-options">

  <li><a href="#" class="js-1-plan">1</a></li>

  <li><a href="#" class="js-2-plan">2</a></li>

  <li><a href="#" class="js-3-plan">3</a></li>

  <li><a href="#" class="js-4-plan">4</a></li>

</ul><!--/.js-filter-options -->
  
<select class="js-dropdown-filter">

  <option value="popular">Popular</option>

  <option value="high-low">Price Highest to Lowest</option>

  <option value="low-high">Price Lowest to Highest</option>

</select><!--/.js-dropdown-filter -->

<section class="js-filter-results">

  <section class="js-filter-results-plans js-1-plan" data-order="1">

    <div class="price">

        <span class="price__amount">24</span>

    </div><!--/.price -->

  </section><!--/.js-filter-results-plans -->

  <section class="js-filter-results-plans js-1-plan" data-order="2">

    <div class="price">

        <span class="price__amount">34</span>

    </div><!--/.price -->

  </section><!--/.js-filter-results-plans -->
  
    <section class="js-filter-results-plans js-1-plan" data-order="3">

    <div class="price">

        <span class="price__amount">33</span>

    </div><!--/.price -->

  </section><!--/.js-filter-results-plans -->
  
    <section class="js-filter-results-plans js-1-plan" data-order="4">

    <div class="price">

        <span class="price__amount">92</span>

    </div><!--/.price -->

  </section><!--/.js-filter-results-plans -->

  <section class="js-filter-results-plans js-2-plan h-hidden" data-order="1">

    <div class="price">

        <span class="price__amount">44</span>

    </div><!--/.price -->

  </section><!--/.js-filter-results-plans -->

  <section class="js-filter-results-plans js-2-plan h-hidden" data-order="2">

    <div class="price">

        <span class="price__amount">55</span>

    </div><!--/.price -->

  </section><!--/.js-filter-results-plans -->

  <section class="js-filter-results-plans js-3-plan h-hidden" data-order="1">

    <div class="price">

        <span class="price__amount">66</span>

    </div><!--/.price -->

  </section><!--/.js-filter-results-plans -->
  
    <section class="js-filter-results-plans js-3-plan h-hidden" data-order="2">

    <div class="price">

        <span class="price__amount">42</span>

    </div><!--/.price -->

  </section><!--/.js-filter-results-plans -->

    <section class="js-filter-results-plans js-3-plan h-hidden" data-order="3">

    <div class="price">

        <span class="price__amount">109</span>

    </div><!--/.price -->

  </section><!--/.js-filter-results-plans -->
  
    <section class="js-filter-results-plans js-3-plan h-hidden" data-order="3">

    <div class="price">

        <span class="price__amount">57</span>

    </div><!--/.price -->

  </section><!--/.js-filter-results-plans -->

  <section class="js-filter-results-plans js-4-plan h-hidden" data-order="1">

    <div class="price">

        <span class="price__amount">19</span>

    </div><!--/.price -->

  </section><!--/.js-filter-results-plans -->
  
    <section class="js-filter-results-plans js-4-plan h-hidden" data-order="2">

    <div class="price">

        <span class="price__amount">11</span>

    </div><!--/.price -->

  </section><!--/.js-filter-results-plans -->
 
 </section><!--/.js-filter-results -->