views:

251

answers:

3

Honestly, I'm not even sure the best way to go about this, but essentially, I have a function in an include file that takes a $type parameter and then will retrieve/print results from my db based on the $type passed into it... What I'm trying to do is have a series of links on a page that, when you click on a certain link, will run the function and display the results accordingly...

So, on the initial load of the page, there is a table that displays everything (and I'm simplifying the table greatly...)

<table>
<tr><th>Item</th><th>Type</th></tr>
<tr><td>Milk</td><td>Dairy</td></tr>
<tr><td>Yogurt</td><td>Dairy</td></tr>
<tr><td>Chicken</td><td>Meat</td></tr>
<tr><td>Zucchini</td><td>Vegetable</td></tr>
<tr><td>Cucumber</td><td>Vegetable</td></tr>
</table>

And, then, in a sidebar, I have a series of links:

<a href="#">Dairy</a>
<a href="#">Meat</a>
<a href="#">Vegetable</a>

I'd like to filter the initial table (and back and forth, etc.) based on the link that is clicked, so that if the user clicks "Vegetable", the function from my include file will run and filter the table to show only "Vegetable" types...

+2  A: 

The first idea that comes to mind is to add a class attribute to the <tr> tags and id attribs to the <a> tags so that you can easily filter that way:

<tr class="dairy"><td>Milk</td><td>Dairy</td></tr>
<tr class="meat"><td>Chicken</td><td>Meat</td></tr>

<a href="#" id="dairy">Dairy</a>
<a href="#" id="meat">Meat</a>

Then in your JavaScript (I'm using jQuery here):

$('a').click(function(evt){
    var myId = $(this).attr('id');

    $('tr').each(function(idx, el){
        if ($(el).hasClass(myId))
        {
            $(el).show();
        }
        else
        {
            $(el).hide();
        }
    });
});

This has the added benefit of allowing you to localize the text without having to change your code.

Darrell Brogdon
I like this, and considered it, but there's pagination at work here as well... If the table is 100 rows, it only displays 20 at a time with links to prev / next / page #... If I do it this way, will the pagination still work, because I thought it wouldn't?
phpN00b
No, you're right. This would break pagination. However you could store in a cookie that the user only wants to see items of a certain type and then do a $('a').click() when the page refreshes if that cookie is found.
Darrell Brogdon
Or you can append a hash e.g. '#dairy' to the 'next/prev' urls and evaluate that value with jQuery on page load. This way, there is no need for cookies.You can do something like this: "var filter = window.location.hash ? '[id=' + window.location.hash.substring(1, window.location.hash.length) + ']' : false;"
Felix Kling
Ok, thanks Felix, btw, for your addendum... For now, I'm happy with taking out the pagination, but I'll likely play with your solution when I have a little more time :) So, my question is basically answered, but as a side note (not sure if I should start a whole new thread for this or not), but if there are no rows that are found after clicking on the filter, is there a way to return text that says 'No rows found'?
phpN00b
I edited my answer to be more complete and also added a remark regarding the number of rows with tables. I'm sure you can count the number of rows that are selected ($('tr').hasClass(myId)) and show some div with this text in it if count == 0. But I am not that familiar jQuery to say, how you can count that ;)
Felix Kling
A: 

If youre printing out the whole tabel up front there is no need to go back to the server you can simple hide all teh rows of a given type. For example with jQuery:

    $('#sidebar a').click(function(){
      // grab the text content of the a tag conver to lowercase
      var type = $(this).text().toLowerCase();

      /* filter all the td's in the table looking for our specified type then hid the 
       * row that they are in
       */
      $('#my_data_table td').contents().filter(function(){
         return this.nodeType == 3 && this.toLowerCase() == type;
      }).parent('tr').hide();

      return false;
    });

Really though the suggestion abotu adding a class to the TR is better because filtering on text content can get tricky if there is content youre not expecting for some reason (hence my conversion to all lower case to help with this).

prodigitalson
+1  A: 

Ok I created a proper answer. You can do it the way Darrel proposed it. This is just an extension for the paging thing to avoid cookies:

$('a').click(function(evt){
    var myId = $(this).attr('id');


    // append a idndicator to the current url
    var location = "" + document.location + "";
    location = location.split('#',1);
    document.location = location + '#' + $(this).attr('id');


    //append to next and previous links
    $('#nextlink').attr({
        'href': $('#nextlink').attr('href') + '#' + $(this).attr('id')
    });
    $('#previouslink').attr({
        'href': $('#previouslink').attr('href') + '#' + $(this).attr('id')
    });

    $('tr').each(function(idx, el){
        if ($(el).hasClass(myId))
        {
            $(el).show();
        }
        else
        {
            $(el).hide();
        }
    });
});

Some code that is executed after page load:

var filter = window.location.hash ? '[id=' + window.location.hash.substring(1, window.location.hash.length) + ']' : false;
if(filter)
    $('a').filter(filter).click();

This simulates/executes a click on page load on the link with the specific id.

But in general, if you have a large database, you should filter it directly with SQL in the backend. This would make the displayed table more consistent. For example if page 1 may only have 3 rows of class 'dairy' and on page 2 10 of class 'dairy'.

Felix Kling