Reputation: 1921
I'm finding some really strange behavior of the filter function which I cannot work out.
I have a list of table rows that have certain text in a custom data-filter attribute. A user types text into a text box and the page automatically filters the table rows using jQuery, based on what's in the data-filter attribute:
$('tbody > tr').hide();
var validTextElements = findMatchingTextRows($('tbody > tr'));
validTextElements.show();
function findMatchingTextRows(elements) {
var textFilterInput = $('#tb_text_filter').val();
textFilterInput = textFilterInput.toLowerCase();
return elements.filter('tr[data-filter*=\'' + textFilterInput + '\']');
}
All works fine unless I have a table with one row in it. In this case, even when the user inputs an empty string (in which case I expect no filtering and the list to remain the same), elements.filter('tr[data-filter*=\'' + textFilterInput + '\']')
returns an empty list, but when there are multiple items in elements
, and the user inputs an empty string, the list remains the same.
There seems no difference between the single element and multiple elements, if I have it working with multiple elements, then I delete all except one from the HTML in Chrome developer tools, it stops working.
Why could this be happening?
Upvotes: 0
Views: 102
Reputation: 450
I suspect some of the confusion is arising from your interpretation of the behaviour of the 'attribute contains' selector. If the value provided is an empty string, nothing is matched.
https://drafts.csswg.org/selectors-3/#attribute-selectors
The relevant section defines the selector thus:
Represents an element with the att attribute whose value contains at least > one instance of the substring "val". If "val" is the empty string then the > selector does not represent anything.
JQuery's filter function will filter the matched elements to those which match the selector:
Reduce the set of matched elements to those that match the selector or pass the function's test
In your case, this is none of them, so the filter function returns an empty jQuery object. An empty string should filter out all rows, not leave them unfiltered, as you indicate that you expect.
It's hard to surmise exactly what is happening in your original code, but I suspect something is throwing an error and the filtering doesn't occur at all when your string is empty. If you're able to replicate the exact issue, update your fiddle and I'll see if I can help further.
Upvotes: 2