forked from sunnywalker/jQuery.FilterTable
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjquery.filtertable.js
More file actions
132 lines (130 loc) · 9.18 KB
/
jquery.filtertable.js
File metadata and controls
132 lines (130 loc) · 9.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/**
* jquery.filterTable
*
* This plugin will add a search filter to tables. When typing in the filter,
* any rows that do not contain the filter will be hidden.
*
* Utilizes bindWithDelay() if available. https://github.com/bgrins/bindWithDelay
*
* @version v1.5.2
* @author Sunny Walker, swalker@hawaii.edu
*/
(function($) {
var jversion = $.fn.jquery.split('.'), jmajor = parseFloat(jversion[0]), jminor = parseFloat(jversion[1]);
if (jmajor<2 && jminor<8) { // build the pseudo selector for jQuery < 1.8
$.expr[':'].filterTableFind = function(a, i, m) { // build the case insensitive filtering functionality as a pseudo-selector expression
return $(a).text().toUpperCase().indexOf(m[3].toUpperCase())>=0;
};
} else { // build the pseudo selector for jQuery >= 1.8
$.expr[':'].filterTableFind = jQuery.expr.createPseudo(function(arg) {
return function(el) {
return $(el).text().toUpperCase().indexOf(arg.toUpperCase())>=0;
};
});
}
$.fn.filterTable = function(options) { // define the filterTable plugin
var defaults = { // start off with some default settings
autofocus: false, // make the filter input field autofocused (not recommended for accessibility)
callback: null, // callback function: function(term, table){}
containerClass: 'filter-table', // class to apply to the container
containerTag: 'p', // tag name of the container
hideTFootOnFilter: false, // if true, the table's tfoot(s) will be hidden when the table is filtered
highlightClass: 'alt', // class applied to cells containing the filter term
inputSelector: null, // use the element with this selector for the filter input field instead of creating one
inputName: '', // name of filter input field
inputType: 'search', // tag name of the filter input tag
label: 'Filter:', // text to precede the filter input tag
minRows: 8, // don't show the filter on tables with less than this number of rows
placeholder: 'search this table', // HTML5 placeholder text for the filter field
quickList: [], // list of phrases to quick fill the search
quickListClass: 'quick', // class of each quick list item
quickListGroupTag: '', // tag surrounding quick list items (e.g., ul)
quickListTag: 'a', // tag type of each quick list item (e.g., a or li)
visibleClass: 'visible' // class applied to visible rows
},
hsc = function(text) { // mimic PHP's htmlspecialchars() function
return text.replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>');
},
settings = $.extend({}, defaults, options); // merge the user's settings into the defaults
var doFiltering = function(table, q) { // handle the actual table filtering
var tbody=table.find('tbody'); // cache the tbody element
if (q==='') { // if the filtering query is blank
tbody.find('tr').show().addClass(settings.visibleClass); // show all rows
tbody.find('td').removeClass(settings.highlightClass); // remove the row highlight from all cells
if (settings.hideTFootOnFilter) { // show footer if the setting was specified
table.find('tfoot').show();
}
} else { // if the filter query is not blank
tbody.find('tr').hide().removeClass(settings.visibleClass); // hide all rows, assuming none were found
if (settings.hideTFootOnFilter) { // hide footer if the setting was specified
table.find('tfoot').hide();
}
tbody.find('td').removeClass(settings.highlightClass).filter(':filterTableFind("'+q.replace(/(['"])/g,'\\$1')+'")').addClass(settings.highlightClass).closest('tr').show().addClass(settings.visibleClass); // highlight (class=alt) only the cells that match the query and show their rows
}
if (settings.callback) { // call the callback function
settings.callback(q, table);
}
}; // doFiltering()
return this.each(function() {
var t = $(this), // cache the table
tbody = t.find('tbody'), // cache the tbody
container = null, // placeholder for the filter field container DOM node
quicks = null, // placeholder for the quick list items
filter = null, // placeholder for the field field DOM node
created_filter = true; // was the filter created or chosen from an existing element?
if (t[0].nodeName==='TABLE' && tbody.length>0 && (settings.minRows===0 || (settings.minRows>0 && tbody.find('tr').length>settings.minRows)) && !t.prev().hasClass(settings.containerClass)) { // only if object is a table and there's a tbody and at least minRows trs and hasn't already had a filter added
if (settings.filterSelector && $(settings.filterSelector).length===1) { // use a single existing field as the filter input field
filter = $(settings.filterSelector);
container = filter.parent(); // container to hold the quick list options
created_filter = false;
} else { // create the filter input field (and container)
container = $('<'+settings.containerTag+' />'); // build the container tag for the filter field
if (settings.containerClass!=='') { // add any classes that need to be added
container.addClass(settings.containerClass);
}
container.prepend(settings.label+' '); // add the label for the filter field
filter = $('<input type="'+settings.inputType+'" placeholder="'+settings.placeholder+'" name="'+settings.inputName+'" />'); // build the filter field
}
if (settings.autofocus) { // add the autofocus attribute if requested
filter.attr('autofocus', true);
}
if ($.fn.bindWithDelay) { // does bindWithDelay() exist?
filter.bindWithDelay('keyup', function() { // bind doFiltering() to keyup (delayed)
doFiltering(t, $(this).val());
}, 200);
} else { // just bind to onKeyUp
filter.bind('keyup', function() { // bind doFiltering() to keyup
doFiltering(t, $(this).val());
});
} // keyup binding block
filter.bind('click search', function() { // bind doFiltering() to click and search events
doFiltering(t, $(this).val());
});
if (created_filter) { // add the filter field to the container if it was created by the plugin
container.append(filter);
}
if (settings.quickList.length>0) { // are there any quick list items to add?
quicks = settings.quickListGroupTag ? $('<'+settings.quickListGroupTag+' />') : container;
$.each(settings.quickList, function(index, value) { // for each quick list item...
var q = $('<'+settings.quickListTag+' class="'+settings.quickListClass+'" />'); // build the quick list item link
q.text(hsc(value)); // add the item's text
if (q[0].nodeName==='A') {
q.attr('href', '#'); // add a (worthless) href to the item if it's an anchor tag so that it gets the browser's link treatment
}
q.bind('click', function(e) { // bind the click event to it
e.preventDefault(); // stop the normal anchor tag behavior from happening
filter.val(value).focus().trigger('click'); // send the quick list value over to the filter field and trigger the event
});
quicks.append(q); // add the quick list link to the quick list groups container
}); // each quick list item
if (quicks!==container) {
container.append(quicks); // add the quick list groups container to the DOM if it isn't already there
}
} // if quick list items
if (created_filter) { // add the filter field and quick list container to just before the table if it was created by the plugin
t.before(container);
}
} // if the functionality should be added
}); // return this.each
}; // $.fn.filterTable
})(jQuery);