M. Gar M. Gar - 6 months ago 14
jQuery Question

Show only the exact match

I have been learning JS and JQuery and recently I have been playing with filter the content, rigth now I'm try to use several filters to show and hide rows from a table, check the JSFiddle. My problem is that I use a

<select>
element to filter by the name
Search FN
and one of the options is
Mark
but if I choose
Mark
also shows me the row with the name
Marky
so How can I show only the
Mark
row? the exact match
.

HTML
<div class="row">
<span class="col-xs-3">
<span class="input-group">
<span class="input-group-addon">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span>
</span>
<input class="form-control" id="searchbox" type="text" name="searchbox" placeholder="Search" />
</span>
</span>
<span class="col-xs-3">
<select class="form-control" id="listfirst" name="listfirst">
<option value="" selected="selected">Search FN</option>
<option value="1">Mark</option>
<option value="2">Jacob</option>
<option value="3">Larry</option>
</select>
</span>
<span class="col-xs-3">
<select class="form-control" id="listlast" name="listlast">
<option value="" selected="selected">Search LN</option>
<option value="1">Otto</option>
<option value="2">Thornton</option>
<option value="3">the Bird</option>
</select>
</span>
<span class="col-xs-3">
<select class="form-control" id="listuser" name="listuser">
<option value="" selected="selected">Search UN</option>
<option value="1">@mdo</option>
<option value="2">@fat</option>
<option value="3">@twitter</option>
</select>
</span>
</div>
<table class="table table-hover">
<thead>
<tr>
<th>#</th>
<th>First Name</th>
<th>Last Name</th>
<th>Username</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td class="fn">Mark</td>
<td class="ln">Otto</td>
<td class="un">@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td class="fn">Jacob</td>
<td class="ln">Thornton</td>
<td class="un">@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td class="fn">Larry</td>
<td class="ln">the Bird</td>
<td class="un">@twitter</td>
</tr>
<tr>
<th scope="row">4</th>
<td class="fn">Marky</td>
<td class="ln">Thornton</td>
<td class="un">@twitter</td>
</tr>
</tbody>
</table>


And here's the script

JS
function filter() {
var box = $('#searchbox').val().toLowerCase();
var listf = $('#listfirst :selected').text().toLowerCase();
var listl = $('#listlast :selected').text().toLowerCase();
var listu = $('#listuser :selected').text().toLowerCase();
if (listf == 'search fn') {
listf = '';
}
if (listl == 'search ln') {
listl = '';
}
if (listu == 'search un') {
listu = '';
}
if (box != '' || listf != '' || listl != '' || listu != '') {
$('table > tbody > tr').hide().filter(function () {
var show = true;
var texttr = $(this).text().toLowerCase();
var textfn = $(this).find('td.fn').text().toLowerCase();
var textln = $(this).find('td.ln').text().toLowerCase();
var textun = $(this).find('td.un').text().toLowerCase();
if (box != '' && texttr.indexOf(box) == -1) {
show = false;
} else if (listf != '' && textfn.indexOf(listf) == -1) {
show = false;
} else if (listl != '' && textln.indexOf(listl) == -1) {
show = false;
} else if (listu != '' && textun.indexOf(listu) == -1) {
show = false;
}
return show;
}).show();
} else {
if (box == '') {
$('table > tbody > tr').show();
} else if (listf == '') {
$('table > tbody > tr').show();
} else if (listl == '') {
$('table > tbody > tr').show();
} else if (listu == '') {
$('table > tbody > tr').show();
}
}
};
$('#searchbox').keyup(filter);
$('#listfirst').change(filter);
$('#listlast').change(filter);
$('#listuser').change(filter);


Any help is appreciated =) sorry for my bad english.

EDIT: This is how looks the end code: solution

Answer

Within the body of your filter function you're using indexOf() to determine whether results will be removed. Because the string "Mark" is within "Marky" a non-negative index will be returned meaning the rows wont be removed in that case. Instead try comparing the literal string values like so:

   if (box != '' && texttr != box) {
            show = false;

Which means the overall function will look like this:

function filter() {
    var box = $('#searchbox').val().toLowerCase();
    var listf = $('#listfirst :selected').text().toLowerCase();
    var listl = $('#listlast :selected').text().toLowerCase();
    var listu = $('#listuser :selected').text().toLowerCase();
    if (listf == 'search fn') {
        listf = '';
    }
    if (listl == 'search ln') {
        listl = '';
    }
    if (listu == 'search un') {
        listu = '';
    }
    if (box != '' || listf != '' || listl != '' || listu != '') {
        $('table > tbody > tr').hide().filter(function () {
            var show = true;
            var texttr = $(this).text().toLowerCase();
            var textfn = $(this).find('td.fn').text().toLowerCase();
            var textln = $(this).find('td.ln').text().toLowerCase();
            var textun = $(this).find('td.un').text().toLowerCase();
            if (box != '' && texttr != box) {
                show = false;
            } else if (listf != '' && textfn != listf) {
                show = false;
            } else if (listl != '' && textln != listl) {
                show = false;
            } else if (listu != '' && textun != listu) {
                show = false;
            }
            return show;
        }).show();
    } else {
        if (box == '') {
            $('table > tbody > tr').show();
        } else if (listf == '') {
            $('table > tbody > tr').show();
        } else if (listl == '') {
            $('table > tbody > tr').show();
        } else if (listu == '') {
            $('table > tbody > tr').show();
        }
    }
};
$('#searchbox').keyup(filter);
$('#listfirst').change(filter);
$('#listlast').change(filter);
$('#listuser').change(filter);

Working example: https://jsfiddle.net/Jason_Graham/oau6og5u/