FilterTable introduces my "Stuff I Wrote and Never Released Because I Was Too Busy" series—a JavaScript class designed to turn plain HTML tables into interactive tools. I built this to solve a recurring problem: making table data manageable without fuss. This documentation guides you through setup and usage, using a sample table with five columns: id, last name, first name, gender, and age. Each example highlights a core feature, ending with a full-featured setup.

What FilterTable Is

FilterTable enhances any HTML table with a header row. It adds text search, enum filters (dropdowns), range filters (for numbers), sortable columns, and pagination. It analyzes your data to apply these features automatically where they fit. English serves as the default language, but translation remains an option. No fluff—just functionality.

Sample Table

Here is the table we use for examples:  
<table id="peopleTable">
    <thead>
        <tr>
            <th>ID</th>
            <th>Last Name</th>
            <th>First Name</th>
            <th>Gender</th>
            <th>Age</th>
        </tr>
    </thead>
    <tbody>
        <tr><td>1</td><td>Smith</td><td>John</td><td>Male</td><td>34</td></tr>
        <tr><td>2</td><td>Johnson</td><td>Emily</td><td>Female</td><td>28</td></tr>
        <tr><td>3</td><td>Lee</td><td>Michael</td><td>Male</td><td>45</td></tr>
        <tr><td>4</td><td>Brown</td><td>Sarah</td><td>Female</td><td>31</td></tr>
        <tr><td>5</td><td>Davis</td><td>James</td><td>Male</td><td>39</td></tr>
    </tbody>
</table>

Getting Started

The script has no dependencies, add a <script> tag to your <head> and it's ready to go.  Bootstrap 5 and Font Awesome support are baked in, but not required.

Basic Activation

You could activate FilterTable on your table with no configuration, but it wouldn't do anything.  Out of the box, it's not sortable, or filterable.  You MUST configure it.  Let's start with its namesake function.

Text Filter

const config = {
    filterableColumns: [1, 2] // Last Name, First Name
};
const filterTable = new FilterTable('peopleTable', config);

You'll get this result.  Type any name, first or last, and the table will render only the matches.  Checkboxes indicate which columns are being filtered.  Check and uncheck to limit which columns the filter applies to.

ID Last Name First Name Gender Age
1 Smith John Male 34
2 Johnson Emily Female 28
3 Lee Michael Male 45
4 Brown Sarah Female 31
5 Davis James Male 39

Enum Filter

Generate dropdowns for columns with repeating values, like gender.  

const config = {
    enumColumns: 3 // Gender, in this case - but you can select multiple columns like [1,2,3]
};
const filterTable = new FilterTable('peopleTable', config);

A dropdown appears above the table for the Gender column, offering "All," "Male," and "Female." Select "Female" to show only Emily Johnson and Sarah Brown. The values are selected from those found in the table column.

ID Last Name First Name Gender Age
1 Smith John Male 34
2 Johnson Emily Female 28
3 Lee Michael Male 45
4 Brown Sarah Female 31
5 Davis James Male 39

Range Filters

For purely numeric columns, you can set up range filters.  As with the enums, the min and max values are selected from the table column itself. Selecting min and max values reduces the table entries to show only those within the range.

const config = {
    rangeColumns: {
        4: {} // an empty object picks the available range. defaultMin and defaultMax optional
    }
};
const filterTable = new FilterTable('peopleTable', config);

Two numeric filters appear, allowing you to filter by min and max values in the Age column.

ID Last Name First Name Gender Age
1 Smith John Male 34
2 Johnson Emily Female 28
3 Lee Michael Male 45
4 Brown Sarah Female 31
5 Davis James Male 39

Sortable Columns

There's no reason to stop with filters, let's jump into the sort feature. Simple to configure, powerful to behold.

const config = {
    sortableColumns: [0,1,2,3,4], // Let's sort by everything
    defaultSortColumn: 0, // ID, this setting is optional - defaults to the default table order
    defaultSortDirection: 'asc' // asc or desc - optional, defaults to asc
};
const filterTable = new FilterTable('peopleTable', config);
ID Last Name First Name Gender Age
1 Smith John Male 34
2 Johnson Emily Female 28
3 Lee Michael Male 45
4 Brown Sarah Female 31
5 Davis James Male 39

Pagination

There's nothing worse than a table that never ends, or having to scroll all the way back up from the bottom of a neverending table just to sort!

const config = {
    rowsPerPageOptions: [2,4,6], // what pagination options are visible to the user, defaults to [5,10,15]
};
const filterTable = new FilterTable('peopleTable', config);

When there aren't enough rows to paginate - no pagination is displayed.

ID Last Name First Name Gender Age
1 Smith John Male 34
2 Johnson Emily Female 28
3 Lee Michael Male 45
4 Brown Sarah Female 31
5 Davis James Male 39

Kitchen Sink Example

All features combined, and a much expanded table (50 entries). I even altered a few of the language strings.

const config = {
    filterableColumns: [1, 2],                // Last Name, First Name for text search
    enumColumns: 3,                           // Gender for dropdown
    rangeColumns: {
        4: { defaultMin: 30, defaultMax: 40 } // Age for range filter
    },
    sortableColumns: [0, 1, 2, 3, 4],        // All columns sortable
    defaultSortColumn: 1,                     // Start sorted by Last Name
    defaultSortDirection: 'asc',
    rowsPerPageOptions: [2, 4, 6],            // Pagination options
    language: {
        searchLabel: "Find",
        enumAllOption: "Any",
        paginationNext: "Forward"
    }
};
const filterTable = new FilterTable('peopleTable', config);
ID Last Name First Name Gender Age
1 Smith John Male 34
2 Johnson Emily Female 28
3 Lee Michael Male 45
4 Brown Sarah Female 31
5 Davis James Male 39
6 Brown Sarah Female 25
7 Jones Michael Male 40
8 Miller Jessica Female 35
9 Davis Chris Male 18
10 Garcia Laura Female 22
11 Martinez David Male 28
12 Hernandez Anna Female 19
13 Lopez Daniel Male 33
14 Gonzalez Maria Female 27
15 Wilson Paul Male 45
16 Anderson Linda Female 50
17 Thomas Mark Male 60
18 Moore Patricia Female 55
19 Jackson Steven Male 42
20 White Barbara Female 38
21 Harris Kevin Male 29
22 Martin Lisa Female 24
23 Thompson Brian Male 31
24 Garcia Angela Female 26
25 Martinez Jason Male 34
26 Hernandez Carol Female 21
27 Lopez Scott Male 37
28 Gonzalez Betty Female 32
29 Wilson Frank Male 41
30 Anderson Sharon Female 36
31 Thomas Greg Male 48
32 Moore Deborah Female 44
33 Jackson Ray Male 39
34 White Helen Female 43
35 Harris George Male 47
36 Martin Ruth Female 49
37 Thompson Edward Male 52
38 Garcia Margaret Female 53
39 Martinez Patrick Male 54
40 Hernandez Donna Female 56
41 Lopez Henry Male 58
42 Gonzalez Virginia Female 59
43 Wilson Albert Male 61
44 Anderson Joan Female 62
45 Thomas Arthur Male 63
46 Moore Gloria Female 64
47 Jackson Howard Male 65
48 White Theresa Female 66
49 Harris Louis Male 67
50 Martin Janet Female 68

Language Replacement

The language object in configuration has options to replace all English strings with the language strings of your choice. This example straight out of Grok, replaces English with Spanish.


    language: {
        searchLabel: "Buscar",                // Replaces "Search"
        rangeMinPlaceholder: "Mín ({min})",   // Replaces "Min ({min})"
        rangeMaxPlaceholder: "Máx ({max})",   // Replaces "Max ({max})"
        rangeSeparator: "a",                  // Replaces "to"
        enumAllOption: "Todos",               // Replaces "All"
        rowsPerPageLabel: "Filas por página:",// Replaces "Rows per page:"
        paginationPrevious: "Anterior",       // Replaces "Previous"
        paginationNext: "Siguiente",          // Replaces "Next"
        paginationAriaLabel: "Paginación de tabla", // Replaces "Table pagination"
        sortTitle: "Haga clic para ordenar"   // Replaces "Click to sort"
    }

Why is this software free?

I’m ditching the freemium game and giving this software to the Joomla crowd for free. It’s a nod to “Jumla”—Swahili for “all together”—because fragmentation sucks, and I’d rather focus on innovation and paid gigs. Use it, build with it, and if you need custom work, I’m super into that.

What's The Catch?

There isn’t one! I’m all about building tools that empower the Joomla community and spark creativity. This software’s free because I’d rather see it in your hands - fueling awesome projects. If you really feel like paying something, I’d appreciate a review in the Joomla Extension Directory—your feedback means a lot!