4
\$\begingroup\$

This plugin is meant to filter through a table based on column header text that matches options given to it. check it out here: Filter Table Plugin

Plugin code below for reference:

//framework from http://jqueryboilerplate.com/
; (function ($, window, document, undefined) {

    var pluginName = "filterTable",
        defaults = {
        };
    function Plugin(element, options) {
        this.element = element;

        this.options = $.extend({}, defaults, options);

        this._defaults = defaults;
        this._name = pluginName;

        this.init();
    }

    Plugin.prototype = {

        init: function () {

            $el = $(this.element);
            $table = $('#' + $el.data('filtertable'));
            var filterColumnNames = ($el.attr('data-filtercolumns')).split(',');
            var filterColumns = new Array();
            var altRowCSS = $el.data('filteralternatingcss');

            //get the column index of the column we'll be filtering on
            $table.find('th').each(function (i) {
                for (j in filterColumnNames) {
                    if ($(this).text().trim() == filterColumnNames[j]) {
                        filterColumns.push(i + 1);
                    }
                }
            });

            $el.keyup(function () {
                var query = $(this).val();
                var numDisplayed = 0;
                //remove any no result warnings
                $table.find('#noResultsRow').remove();
                //hide all rows
                $table.find('tr').removeClass(altRowCSS).hide();
                //show the header row
                $table.find('tr:first').show();
                for (i in filterColumns) {
                    $table.find('tr td:nth-child(' + filterColumns[i] + ')').each(function () {
                        if ($(this).text().toLowerCase().indexOf(query.toLowerCase()) >= 0) {
                            $(this).parent().show();
                            numDisplayed++;
                        }
                    });
                }
                if (numDisplayed == 0) {
                    $tr = $('<tr>');
                    $tr.attr('id', 'noResultsRow');
                    $td = $('<td>').attr('colspan', $table.children('tbody').children('tr').children('td').length);
                    $td.html('No results for filter "' + query + '."');
                    $td.css({ textAlign: 'center' });
                    $tr.append($td);
                    $table.children('tbody').append($tr);
                }
                $table.find('tr:visible :odd').addClass(altRowCSS);
            });
            $el.keyup();
        },
    };

    $.fn[pluginName] = function (options) {
        return this.each(function () {
            if (!$.data(this, "plugin_" + pluginName)) {
                $.data(this, "plugin_" + pluginName, new Plugin(this, options));
            }
        });
    };

})(jQuery, window, document);

Any improvements I can make?

\$\endgroup\$
2
  • \$\begingroup\$ Forgot to mention one thing I might add is matching against whole words only - instead of 'ter' matching filter and terminal, it would only match terminal. \$\endgroup\$
    – Dakine83
    Commented Apr 4, 2013 at 19:26
  • 1
    \$\begingroup\$ Did you mean you're only matching at the start of the word? Neither terminal or filter are whole word matches of ter. \$\endgroup\$ Commented Nov 26, 2013 at 1:38

1 Answer 1

2
\$\begingroup\$
  1. You have:

    this._defaults = defaults;
    

    This is redundant as the declaration :

    var pluginName = "filterTable",
        defaults = {
        };
    

    Can be accessed anywhere in your plugin.

  2. Declare all variables that you use. This is a really good practice to have change lines like:

     $el = $(this.element);
     $table = $('#' + $el.data('filtertable'));
    

    to:

    var $el = $(this.element);
    var $table = $('#' + $el.data('filtertable'));
    

    JavaScript will let you use them without but you'll run into issues otherwise.

  3. Variables need meaningful names so their lives don't seem meaningless and they despair.

    Invective! Verb your expletive nouns!

    $table.find('th').each(function (i)
    {
        for (j in filterColumnNames)
        {
            if ($(this).text().trim() == filterColumnNames[j])
            {
                 filterColumns.push(i + 1);
            }
        }
     });
    

    What is i? index? columnIndex?
    What is j? currentColumnName?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.