views:

204

answers:

2

I have a table where each row has a category column and a sub-category column. I need to let the users chose a category to filter, and then only show the sub-categories that are related so they can filter further. I'm thinking it could be a select drop-down list and only show a second drop-down list when sub-categories exist. I've seen some examples that use server-side scripts (such as Remy Sharp's solution http://remysharp.com/2007/01/20/auto-populating-select-boxes-using-jquery-ajax/) but I just need strictly a client-side jQuery solution. Anyone have suggestions on the best way to do this or examples of it?

A: 

So on your select changes you could fire classifyCategories - of course you'll need to write something to hide the selects that don't match the parent category but this might help you in the row classifying.

<table>
   <tr class="topLevelCategoryA subCategoryC"><td>content</td></tr>
   <tr class="topLevelCategoryB subCategoryC"><td>content</td></tr>
   <tr class="topLevelCategoryD"><td>content</td></tr>
   <tr class="topLevelCategoryZ subCategoryC"><td>content</td></tr>
</table>

function classifyCategories() {
   var parentCategory = $('#mainSelect').val();
   var subCategory = $('#mainSelect').siblings('select:visible').val();
   var query = "." + parentCategory;
   if( subCategory ) {
      query += "." + subCategory;
   }  
   $('table tr').not(query).hide();
}

The premise is using class selectors. $('table tr').not('.topLevelCategoryB.subCategoryC') will only match that configuration, where as $('table tr').not('.topLevelCategoryB') - would match all subcategories..

Dan Heberden
I'm not quite sure I follow. How would the select be setup? Would those class names be the values inside the select options?
Keith
A: 

I like Dan's idea, so I expanded on it (quite a bit). You should be able to paste this into a text editor and watch it work.

Basically, it's using classes on the TRs to show and hide them, and using a larger number of hidden selects to show groups of subcategories.

<script type="text/javascript"
 src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;

<select id="masterCategory">
  <option value="all">All</option>
  <option value="sandwiches">Sandwiches</option>
  <option value="bagels">Bagels</option>
</select>

<div>

  <select id="all">
    <option value="all">All</option>
    <option value="pastrami">Pastrami</option>
    <option value="pbj">PBJ</option>
    <option value="baconranch">Bacon &amp; Ranch</option>
    <option value="jalapeno">Jalapeno</option>
    <option value="onion">Onion</option>
    <option value="poppyseed">Poppyseed</option>
  </select>

  <select id="sandwiches" style="display: none">
    <option value="sandwiches">All</option>
    <option value="pastrami">Pastrami</option>
    <option value="pbj">PBJ</option>
    <option value="baconranch">Bacon &amp; Ranch</option>
  </select>

  <select id="bagels" style="display: none">
    <option value="bagels">All</option>
    <option value="jalapeno">Jalapeno</option>
    <option value="onion">Onion</option>
    <option value="poppyseed">Poppyseed</option>
  </select>

</div>

<table id="content">
  <tr class="sandwiches pastrami pbj"><td>sandwiches pastrami pbj</td></tr>
  <tr class="sandwiches baconranch"><td>sandwiches baconranch</td></tr>
  <tr class="bagels jalapeno"><td>bagels jalapeno</td></tr>
  <tr class="bagels onion poppyseed"><td>bagels onion poppyseed</td></tr>
</table>

<script type="text/javascript">

  $(function(){

    $('select').bind('change', function(){
      var category = $(this).val();

      $('table#content').find('tr').each(function(){
        if($(this).hasClass(category) || category == 'all'){
          $(this).show();
        } else {
          $(this).hide();    
        }
      });
    });

    $('select#masterCategory').bind('change', function(){

      $('select#' + $(this).val()).fadeIn().siblings().fadeOut();

    });

  });

</script>
Doug Avery
The other way to do it might be more DOM-intensive, but require less code overall - you could have an {object} with the categories and subcategories, and populate the subcategory select using your object and some .append() magic. This way, you'd be depending on only two selects for the functionality, but you'd be juggling the contents of one dynamically.
Doug Avery
Oh, and make sure to put "autocomplete='off'" on those selects if you want them to reset to "all" on page refresh.
Doug Avery