(function($){
    var filterableClass = "rowFilterable";
    var filterIndexClass = "rowFilterIndexCol";

    function performFilter(query) {
        //The explicit test for empty is required to stop IE from flipping out
        if (query != "") {
            query = query.toLowerCase().split(" ");
            //For each filterable table, show all rows then hide the ones that don't match
            $("table."+filterableClass+" tr").show();
            $.each(query, function() {
                if (this != "") {
                    $("table."+filterableClass+" tr ."+filterIndexClass+":not(:contains("+this+"))").parent().hide();
                }
            });
        }
        else {
            $("table."+filterableClass+" tr").show();
        }
    }

    $.fn.rowFilter = function(data_from) {

        //Reset the filter box on page reload
        $(document).ready(function() {
            $(data_from).val('');
        });

        //Bind the filtering process to the box after emptying it
        $(data_from).keyup(function() {
            performFilter($(this).val());
        });

        return $(this).each(function(){
            //Iterate over all tables that should be filterable
            return $(this).each(function(){
                //Add a magic class so that we can find the table later
                $(this).addClass(filterableClass);

                //Create a hidden column containing the concatenation of all
                // the text, to use as a search index.  For images, use their
                // alternate text.
                $(this).find("tr:has(td)").each(function(){
                    //var index = $(this).text().toLowerCase();
                    var index = "";
                    $(this).children().each(function(){
                        index += $(this).text().toLowerCase()+" ";
                        img_alt = $(this).find('img').attr('alt');
                        index += img_alt ? img_alt.toLowerCase() + " " : '';
                    });
                    $('<td class="'+filterIndexClass+'"></td>').hide().text(index).appendTo(this);
                });
            });
        });
    };
})(jQuery);