I made a phonebook where I work for internal use. All results are shown in a table. I used to just have this as my function to filter on that table:
function LiveSearch() {
$('input#srch-field').on('keyup', function () {
var rex = new RegExp($(this).val(), 'i');
$('.srch-table tr').hide();
$('.srch-table tr').filter(function () {
return rex.test($(this).text());
}).show();
});
}
But my users are apparently unhappy with this requested function, so they want a filter instead. So I have made a dropdown that supposed to act like a filter. I was then looking at my function and was thinking "How can I modify this, to make it work generally the same?", so I came up with this:
function LiveSearch() {
$('input#srch-field').on('keyup', function () {
var rex = new RegExp($(this).val(), 'i');
var e = document.getElementById("srchFilter");
var filter = e.options[e.selectedIndex].value;
if (filter === 'all') {
$('.srch-table tr').hide();
$('.srch-table tr').filter(function () {
return rex.test($(this).text());
}).show();
} else {
$('.srch-table tr[id=' + filter + ']').hide();
$('.srch-table tr[id=' + filter + ']').filter(function () {
return rex.test($(this).text());
}).show();
}
});
}
The idea is that every value in my select:
<div class="form-group">
<select id="srchFilter" class="form-control">
<option value="all" selected="selected">No Filter</option>
<option value="name">Name</option>
<option value="title">Title</option>
<option value="department">Department</option>
<option value="private-phone">Private Phone</option>
<option value="work-email">Work Email</option>
<option value="work-phone-land">Work Phone Landline</option>
<option value="work-phone-mobile">Work Phone Mobile</option>
</select>
</div>
Corresponds to a Column ID in my table. But if my filter is anything but all
it simply doesn't do any filtering whatsoever. I might just be misunderstanding how the regex works. Could anyone shed some light on it?
EDIT
The code for my Table as request:
<div class="col-lg-6" id="customtable">
<table class="table table-striped" id="tablesorter">
<thead>
<tr>
<th class="col-xs-4" id="name">
Name<span class="glyphicon glyphicon-filter"></span>
</th>
<th class="col-xs-4" id="title">
Title<span class="glyphicon glyphicon-filter"></span>
</th>
<th class="col-xs-4" id="department">
Department<span class="glyphicon glyphicon-filter"></span>
</th>
<th style="display: none;" id="private-phone">
Private Phone
</th>
<th style="display: none;" id="work-email">
Work Email
</th>
<th style="display: none;" id="work-phone-land">
Work Phone Landline
</th>
<th style="display: none;" id="work-phone-mobile">
Work Phone Mobile
</th>
</tr>
</thead>
<tbody class="srch-table" id="srch-table">
<tr>
<td class="col-xs-12"><b>Please Wait...</b></td>
</tr>
</tbody>
</table>
<div class="fl-separator"></div>
</div>
Please note that you are assigning duplicate IDs to the table elements (as I sniff from your JavaScript code). IDs should be unique across an HTML page, and that's why your filter won't work as expected.
You can try to assign a class instead (or and HTML data attribute is recommended). So, for example, the td
related to name
will have a class name
instead of id name
.
And then, your JavaScript code can be changed like this, so that it can leverage class
es instead of id
s:
// ... code truncated for brevity
if (filter === 'all') {
$('.srch-table tr').hide();
$('.srch-table tr').filter(function () {
return rex.test($(this).text());
}).show();
} else {
$('.srch-table tr').hide();
$('.srch-table tr').filter(function () {
return rex.test($(this).find('td.' + filter).text());
}).show();
}
// ... code truncated for brevity
Note the use of dot selector which matches the tr
s which only have td
s with specified class.
Bonus: Since you're using jQuery, these lines:
var e = document.getElementById("srchFilter");
var filter = e.options[e.selectedIndex].value;
can simply be replaced by this line:
var filter = $("#srchFilter").val();
Update:
This is a forked version of your fiddle which works.