$ is a jQuery object, it's just a variable name pointing to jQuery. Don't worry about $ rows, this is just another variable name.
var $rows = $('#table tr');
The right side basically passes the selector to jQuery and tells it to find all the DOM elements that match it. If you know CSS, this is the same principle, #table is an element with id="table" and in combination with tr means selecting all the rows (tr is the html tag of the row table) inside this element.
In pure javascript, this can be written as
var $rows = document.querySelectorAll("#table tr");
The result is a list of items.
Then you will find another element and attach an event listener:
$('#search').keyup(function() { ... });
Note that this is passing another selector to jQuery, which returns the desired element to which you are attaching a keyup event. In JavaScript, this could be:
document.getElementById("search").addEventListener("keyup", function() { ... });
When this keyup event is fired on an element, the function is executed, and you build a string val that contains:
... + $.trim($(this).val()).split(/\s+/).join('\\b)(?=.*\\b') + ...
this in $(this).val() evaluates the element that was found by the #search selector, in this case the input field.
It could be the following in pure javascript:
... + document.getElementById("search").value.trim().split(/\s+/).join('\\b)(?=.*\\b') + ...
If you evaluate this expression, it 1) truncates the spaces, 2) splits the result into an array of strings on each space character, and 3) combines this array with the delimiter \\b)(?=.*\\b
Steps 2) and 3) are basically a String.replace(/\s+/, '\\b)(?=.*\\b') , but faster.
Moving to the last bit, the jQuery show() method is applied to each element in $ rows, which was the list of elements (table rows) that was found at the beginning. This makes each line visible.
Then the filter is applied to this list, it is a cycle through the list of elements that call the function defined inside each element. Note that this in the filter function now refers to the table row being tested, and not to the search field.
If the filter function returns true in the list item, the item remains in the resulting list; if false, it is deleted. The one prepared by RegExp is applied here, and if it matches the function, returns false. Therefore, after filtering, you have a list of elements / lines that do not match, and finally, .hide() , which is a jQuery method, is used to hide all the elements on which it is called. This way you hide lines that do not match.
The code may look something like this in "clean" javascript (it should work now, I fixed the problem cjsmith wrote about in the comments).
var $rows = document.querySelectorAll("#table tr"); document.getElementById("search").addEventListener("keyup", function(e) { var val = '^(?=.*\\b' + e.target.value.trim().split(/\s+/).join('\\b)(?=.*\\b') + ').*$'; var reg = RegExp(val, 'i'); Array.prototype.forEach.call($rows, function(row) { var text = row.textContent.replace(/\s+/g, ' '); row.style.display = reg.test(text) ? 'table-row' : 'none'; }); });
PS. Happy New Year!