Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'Translation from jQuery to JavaScript'

I'm a noobie that has been learning by his own and messing around with javascript and I stumbled upon that nightmare called 'regular expressions'...I kinda know a little bit about them and I been doing fancy stuff, but I'm stuck and I'd like you clarify this to me:

I've been reading and looking for a way to create matches and I tripped on with great answer:

  • How to perform a real time search and filter on a HTML table

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

var $rows = $('#table tr');
$('#search').keyup(function() {

var val = '^(?=.*\\b' + $.trim($(this).val()).split(/\s+/).join('\\b)(?=.*\\b') + ').*$',
    reg = RegExp(val, 'i'),
    text;

$rows.show().filter(function() {
    text = $(this).text().replace(/\s+/g, ' ');
    return !reg.test(text);
}).hide();

});

  • http://jsfiddle.net/dfsq/7BUmG/1133/

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

I kinda understand what is going on there but could somebody break that down and 'translate it in javascript' for me so I can catch the idea better, I barely can do cool stuff with jquery since I'm still studying javascript, I know certain things about the jqueries but not enough to fully understand what he did there and enough about regular expressions to know that the guy who wrote taht code is a genius <3

this is what i understand and please correct me:

var $rows = $('#table tr'); 

it's the scope, the 'target' in which is gonna be looking for the match

pd:that's the first time I see the'$' to declare variables and for what I've looked it sets it as a jQuery object..it's that right?

var val = '^(?=.*\\b' + $.trim($(this).val()).split(/\s+/).join('\\b)(?=.*\\b') + ').*$',
    reg = RegExp(val, 'i'),
    text;

the '$.trim($(this).val()' is equal to $.trim($("#user_input").val()); .......right?

reg = RegExp(val, 'i')

the reg variable works as a constructor to find the match that will be case-insensitive, but shouldn't it be 'reg = new RegExp(val, 'i')' or I can set as it is as well?

here is when I get confused the most

$rows.show().filter(function() {
        text = $(this).text().replace(/\s+/g, ' ');
        return !reg.test(text);
}).hide();

what I can understand is that the matches will be shown only if they pass the filter set by the text variable and the ones who don't will be hidden, I haven't the slightest idea of what the $(this) is equivalent to....in the text variable.. and from there on I have no idea what's going on, I found that .test() returns true or false when it finds a match in the regexp object but why does it have the ! at the beginning?

like image 268
nero Avatar asked Oct 19 '22 19:10

nero


2 Answers

$ is the jQuery object, it's just a variable name that points to jQuery. Don't worry about $rows, that's just another variable name.

var $rows = $('#table tr'); 

The right-hand side is basically passing a selector to jQuery and telling it to find all DOM elements that match it. If you know CSS this is the same principle, #table is an element with id="table" and combined with tr means select all rows (tr being the table row html tag) within that element.

In pure javascript this could be written as

var $rows = document.querySelectorAll("#table tr");

The result is a list of elements.

Then you find another element, and attach an event listener:

$('#search').keyup(function() { ... });

Notice this is passing another selector to jQuery, which returns the desired element, onto which you attach a keyup event. In JavaScript this might be:

document.getElementById("search").addEventListener("keyup", function() { ... });

When that keyup event is triggered on the element the function is executed, and you are building a string val which contains:

... + $.trim($(this).val()).split(/\s+/).join('\\b)(?=.*\\b') + ...

this in $(this).val() evaluates to the element which was found by the #search selector, in this case an input field.

This might be the following in pure javascript:

... + document.getElementById("search").value.trim().split(/\s+/).join('\\b)(?=.*\\b') + ...

If you evaluate that expression, it 1) trims whitespace, 2) splits the result into an array of strings on every whitespace character and 3) joins that array with the delimiter \\b)(?=.*\\b

Steps 2) and 3) are basically a String.replace(/\s+/, '\\b)(?=.*\\b') but quicker.

Moving onto the last bit, the jQuery show() method is applied to each element in $rows, which was that list of elements (table rows) found at the beginning. This makes every row visible.

Then the filter method is applied to that list, this is a loop through the list of elements calling the function defined within on each element. Notice, this within the filter function now refers to the table row being tested, not the search field.

If that filter function returns true on a list item that item remains in the resulting list, if false it is removed. Here that prepared RegExp is applied, and if it matches the function returns false. So after filtering you have a list of elements/rows which do not match, and finally .hide() is applied which is a jQuery method to hide all elements on which it is called. So you hide the rows that don't match.

The code may look something like this in "pure" 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!

like image 174
Nenad Vukicevic Avatar answered Oct 28 '22 16:10

Nenad Vukicevic


var $rows = $('#table tr');

it's the scope, the 'target' in which is gonna be looking for the match

pd:that's the first time i see the'$' to declare variables and for what I've looked it sets it as a jquery object..it's that right?

Yes, $rows is target, but the '$' of sign is actually meaningless, that is an approach of jquery programmers. It's good for remembering a jquery object, "hımmm, this has a '$' at the start, so that must be a jquery object".

In fact var $rows = $('#table tr'); and var rows = $('#table tr'); -> these are same, there aren't any differences between $rows and rows.

-----------------------------------------------------------------------------------------

var val = '^(?=.\b' + $.trim($(this).val()).split(/\s+/).join('\b)(?=.\b') + ').*$', reg = RegExp(val, 'i'),

text; the '$.trim($(this).val()' is equal to $.trim($("#user_input").val()); .......right?

In javascript this refers the event's owner. For the example that you shared, this used in keyup callback function of $('#search') so that means this refers the $("#search").

-----------------------------------------------------------------------------------------

reg = RegExp(val, 'i') the reg variable works as a constructor to find the match that will be case-insensitive, but shouldn't it be 'reg = new RegExp(val, 'i')' or I can set as it is as well?

There are nice explanations of new keyword for Javascript in this question, you can check it.

-----------------------------------------------------------------------------------------

$rows.show().filter(function() {
        text = $(this).text().replace(/\s+/g, ' ');
        return !reg.test(text);
}).hide();

Let's explain it step by step

var $rows = $('#table tr');
  • $rows is an array of tr objects
  • $rows.show() means show all tr tags which are in a table that's id is #table.
  • jQuery is chainable, that means $rows.show() returns $rows again
  • so $rows.show().filter() = $rows.filter
  • again $rows is still is an array of tr objects, so $rows.filter() loops through this object like a for loop, the callback function is processed for each objects in $rows.
  • In a callback function this refers the owner, in this example the owner is the object at that time while filter is looping the $rows.
  • As you said test() returns a bool value.
  • ! is an inverter,

    !true = false

    !false = true

like image 31
Okan Kocyigit Avatar answered Oct 28 '22 16:10

Okan Kocyigit