ul filter and sort

handle sorting and inline filter

by borsna

HTML

<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css">
<div class="filter" data-show="5">

  <input type="search" class="text-filter" placeholder="filter">
  <a href="#" title="Sort alphabetically" class="sort-alfa glyphicon glyphicon-sort-by-alphabet"></a>
  <a href="#" title="Sort numerically" class="sort-num glyphicon glyphicon-sort-by-order-alt"></a>

  <ul>
    <li class="content visible">
      <a href="?subject=Humaniora+och+konst" rel="nofollow"><span id="filterBlockAction" class="glyphicons glyphicons-unchecked"></span>Humaniora och konst<span class="filterBlockBucketCount">527</span></a>
    </li>
    <li class="content visible">
      <a href="?subject=Historia+och+arkeologi" rel="nofollow"><span id="filterBlockAction" class="glyphicons glyphicons-unchecked"></span>Historia och arkeologi<span class="filterBlockBucketCount">503</span></a>
    </li>
    <li class="content visible">
      <a href="?subject=Historia" rel="nofollow"><span id="filterBlockAction" class="glyphicons glyphicons-unchecked"></span>Historia<span class="filterBlockBucketCount">492</span></a>
    </li>
    <li class="content visible">
      <a href="?subject=Arkeologi" rel="nofollow"><span id="filterBlockAction" class="glyphicons glyphicons-unchecked"></span>Arkeologi<span class="filterBlockBucketCount">473</span></a>
    </li>
    <li class="content visible">
      <a href="?subject=Samh%C3%A4llsvetenskap" rel="nofollow"><span id="filterBlockAction" class="glyphicons glyphicons-unchecked"></span>Samhällsvetenskap<span class="filterBlockBucketCount">273</span></a>
    </li>
    <li class="content visible">
      <a href="?subject=Medicin+och+h%C3%A4lsovetenskap" rel="nofollow"><span id="filterBlockAction" class="glyphicons glyphicons-unchecked"></span>Medicin och hälsovetenskap<span class="filterBlockBucketCount">212</span></a>
    </li>
    <li class="content visible">
      <a href="?subject=Statsvetenskap" rel="nofollow"><span...

CSS

body {
  background: #FFF;
  padding: 20px;
  font-family: Helvetica;
}

.filterBlockBucketCount {
  margin-left: 4px;
  font-weight: bold;
}

JavaScript

jQuery(document).ready(function() {
  jQuery("ul li").hide();
  jQuery("ul li").slice(0, 5).show();

  jQuery("a.sort-alfa").click(function() {
    sortUsingNestedText(jQuery(this).siblings('ul'), 'li', 'a', false);
    updateVisibleFilterItems(jQuery(this).siblings('ul'), 'li');
  });

  jQuery("a.sort-num").click(function() {
    sortUsingNestedText(jQuery(this).siblings('ul'), 'li', 'span.filterBlockBucketCount', true);
    updateVisibleFilterItems(jQuery(this).siblings('ul'), 'li');
  });

  jQuery("input.text-filter").keyup(function() {
    var filter = jQuery(this).val();
    console.log(filter);
    filterListByText(jQuery(this).siblings('ul'), 'li', filter)
  });

  jQuery("a.show-more").click(function() {
    var show = parseInt(jQuery(this).parent('div.filter').data('show'));
    show += 10;

    jQuery(this).parent('div.filter').data('show', show);
		updateVisibleFilterItems(jQuery(this).siblings('ul'), 'li');
  });
});

function filterListByText(parent, cildSelector, text) {
  parent.children(cildSelector).removeClass('visible');
  
  parent.children(cildSelector).each(function(){
  	if(jQuery(this).text().toLowerCase().includes(text.toLowerCase())){
    	jQuery(this).addClass('visible');
    }
  });
  
  updateVisibleFilterItems(parent, cildSelector);
}

function updateVisibleFilterItems(parent, childSelector){
  var show = parent.parent("div.filter").data('show');
  parent.children(childSelector).hide();
  parent.children(childSelector+'.visible').slice(0, show).show();
}

function sortUsingNestedText(parent, childSelector, keySelector, reverse) {
  var items = parent.children(childSelector).sort(function(a, b) {
    var vA = $(keySelector, a).text();
    vA = isNaN(vA) ? vA : parseInt(vA);
    var vB = $(keySelector, b).text();
    vB = isNaN(vB) ? vB : parseInt(vB);
    if (reverse) {
      return (vA > vB) ? -1 : (vA < vB) ? 1 : 0;
    } else {
      return (vA < vB) ? -1 : (vA > vB) ? 1 : 0;
    }

  });
  
  parent.append(items);
}

if...