September 11, 201511 yr Good night:) For my current progect we don't use jQuery, so i need to rewrite this function on plain js. $('#search').keyup(function () { var yourtext = $(this).val(); if (yourtext.length > 0) { var abc = $("li").filter(function () { var str = $(this).text(); var re = new RegExp(yourtext, "i"); var result = re.test(str); if (!result) { return $(this); } }).hide(); } else { $("li").show(); } }); Working perfect but i don't want include jquery only for this in my app. I tried this solution but it seems not work. (function () { var searchKey = document.getElementById("search_box"), booksFiltered = document.querySelectorAll(".text blocks"); searchKey.addEventListener("keyup", function () { var yourtext = this.value; for (var i = 0; i < booksFiltered.length; i++) { var a = booksFiltered[i]; if (yourtext.length > 0) { var abc = a.filter(function (el) { var str = el.data; var re = new RegExp(yourtext, "i"); var result = re.test(str); if (!result) { return el; } return result; }); booksArray.classList.add(hid); //hidden } else { booksArray.classList.add(vis); // visible } } }); })(); Please, point me on my mistake. I have headache already:))) Forget to say? that i need to search text only in one page. After searching only needed text have to be on the page,. Rest text articles need to be hidden. Thank you for any advice about my mistakes. Edited September 11, 201511 yr by fleur
September 11, 201511 yr I am assuming your books are stored in a bunch of li elements? This seems a really strange way to get data. In reality you'd be using some kind of backend API that would be supplying you with some JSON data which you could then filter through (Assuming the API contained all the books in the DB, although again - the search function would be more of a task for the Backend, maybe look to doing this: Store a json file and write a basic API in Node that loads that file and is called when you submit the search box - you can use ajax in your client side script to send the search request to the Node API, which can then load the json and use the query to filter out the results. And then send a response back to the client containing the filtered results. Then in your client script you can collate the results into a HTML string and insert them into the DOM. One thing to bear in mind with DOM insertions - they are costly, so don't do them inside of loops. You build up a html string using concatenation for each loop iterration, and then once the loop has exited then push the entire collection to the DOM. A single write to the DOM will be far more efficient than multiple smaller insertions. This whole thing sounds like it would make for an interesting blog post. If I get time at the weekend I'll write something like I am describing here (But the Ajax request will be using jQuery, there's a number of issues doing Ajax with the native DOM API that jQuery has smoothed over.)
September 11, 201511 yr It sounds like you're looking to do more of a list style search. I think JS is suitable for this. Where client-side JS wouldn't be suitable, is any advanced searching and relational data lookups. This is typically backend work, and depending on how many results you're searching through, can be difficult to optimise. I've used List JS on quite a few projects. It's great for dashboards and similar UI where you only need basic searching and filtering. This plugin is well built, the developer has good experience with JS, and it has been performance tested on 1000's of rows. Depending on how many item's you could be searching through, it's worth running some tests first http://www.listjs.com/performance.
September 11, 201511 yr That list.js does look very well written. My argument is (although may not stand in all cases) is: Whatever was used to populate the DOM initially with the list of items should store that data before it inserts it to the DOM, then when you make some kind of query, filter, search you then use the stored data rather than doing lots of DOM lookups, which no matter how well written are many times slower than accessing an object / array in JS. This principle is one of the reasons why React is so fast - manipulating a virtual DOM, is many times faster than the real one. I've have always wondered though, why is the DOM so slow..? On second thought you probably don't need to use the backend to do the searching, if the servers get a lot of traffic it's kind of nice to let the client side deal with searching if they already have the data stored somewhere (assuming it's not many megaybtes in size).. but as a bit of a side project it would be interesting to build anyway. I'm just thinking out aloud though -- as if I were building the whole thing from scratch, of course if you cannot do that then something like list.js would definitley be a good option. Edited September 11, 201511 yr by rbrtsmith
September 11, 201511 yr I think it depends on what you need to do. The last time I used List, it was to search about 50 or so documents on a dashboard grid. It's much faster than querying a DB and returning the results, but in cases where you have larger data sets, you would want to handle this on the server.
September 11, 201511 yr (function () { var searchKey = document.getElementById("search_box"), booksFiltered = document.querySelectorAll(".text blocks"); searchKey.addEventListener("keyup", function () { var yourtext = this.value; for (var i = 0; i < booksFiltered.length; i++) { var a = booksFiltered[i]; if (yourtext.length > 0) { var abc = a.filter(function (el) { var str = el.data; var re = new RegExp(yourtext, "i"); var result = re.test(str); if (!result) { return el; } return result; }); booksArray.classList.add(hid); //hidden } else { booksArray.classList.add(vis); // visible } } }); })(); Shouldn't "el" be declared somewhere ? Or is it a parameter definition that will point to an object created by the filter method, how can that work ??? Edited September 11, 201511 yr by Nillervision
September 11, 201511 yr Shouldn't "el" be declared somewhere ? Or is it a parameter definition that will point to an object created by the filter method, how can that work ??? the filter function is a callback, and el refers to the current element on the array that filter is looping over.
September 11, 201511 yr I think it depends on what you need to do. The last time I used List, it was to search about 50 or so documents on a dashboard grid. It's much faster than querying a DB and returning the results, but in cases where you have larger data sets, you would want to handle this on the server. I don't mean to query the db everytime you do some kind of filtering, i mean when the page first renders the backend must get the data from the database.. so before pushing all that to the Dom, it can be stored as a variable or in localStorage to be later referenced. I think using the DOM as a far as data storage / retreval should be an absolute last resort. I agree that we should do things differently for much larger chunks of data.
September 11, 201511 yr I don't mean to query the db everytime you do some kind of filtering, i mean when the page first renders the backend must get the data from the database.. so before pushing all that to the Dom, it can be stored as a variable or in localStorage to be later referenced. I think using the DOM as a far as data storage / retreval should be an absolute last resort. I agree that we should do things differently for much larger chunks of data. I sort of get that idea of storing the data to use later on. I don't really know enough about it though. I think in this case the data would already be there, and loaded into the DOM. Let's say you're outputting a list of 50 documents on a page into a list, the data is already there to work with, you just have to show/hide items based on a value entered. In some cases, users might not even use the search, so there won't be any performance hit.
September 11, 201511 yr Author Shouldn't "el" be declared somewhere ? Or is it a parameter definition that will point to an object created by the filter method, how can that work ??? No, it's not parameter. I tried to write "this" instead of el, but it doesn't work. I spend several houres for nothing. Can't understand where is my mistake. rbrtsmithrbrtsmith said:"the filter function is a callback, and el refers to the current element on the array that filter is looping over." Yes. But it is not working with it. I write for loop, also doesn't work. Edited September 11, 201511 yr by fleur
September 11, 201511 yr Author I am assuming your books are stored in a bunch of li elements? This seems a really strange way to get data. In reality you'd be using some kind of backend API that would be supplying you with some JSON data which you could then filter through (Assuming the API contained all the books in the DB, although again - the search function would be more of a task for the Backend, maybe look to doing this: Store a json file and write a basic API in Node that loads that file and is called when you submit the search box - you can use ajax in your client side script to send the search request to the Node API, which can then load the json and use the query to filter out the results. And then send a response back to the client containing the filtered results. Then in your client script you can collate the results into a HTML string and insert them into the DOM. One thing to bear in mind with DOM insertions - they are costly, so don't do them inside of loops. You build up a html string using concatenation for each loop iterration, and then once the loop has exited then push the entire collection to the DOM. A single write to the DOM will be far more efficient than multiple smaller insertions. This whole thing sounds like it would make for an interesting blog post. If I get time at the weekend I'll write something like I am describing here (But the Ajax request will be using jQuery, there's a number of issues doing Ajax with the native DOM API that jQuery has smoothed over.) Not li, books is div. And whole app works fine. JSON already here. Everything is fine! Function working in iQuery. I simply need to rewrite this function in vanilla JS. Nothing more:) Ajax maybe used here for loading rest pages into one. But now i have only task that i told. Edited September 11, 201511 yr by fleur
September 11, 201511 yr Author I sort of get that idea of storing the data to use later on. I don't really know enough about it though. I think in this case the data would already be there, and loaded into the DOM. Let's say you're outputting a list of 50 documents on a page into a list, the data is already there to work with, you just have to show/hide items based on a value entered. In some cases, users might not even use the search, so there won't be any performance hit. Yes. you are write. But if your load lots of text block, searching must be here. I don't want to load whole jquery only for one search function Edited September 11, 201511 yr by fleur
September 11, 201511 yr the filter function is a callback, and el refers to the current element on the array that filter is looping over. I see. Thanks
September 11, 201511 yr I see. Thanks If you want any further info on filter then MDN is a good place https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter Their documentation for things like map, reduce and so on are very thorough. also: These high order array methods are really elegant, there's literally no need to use loops when dealing with arrays now, these can be substituted in any instance, their names make things a lot more clear of what is going on Edited September 11, 201511 yr by rbrtsmith
September 11, 201511 yr fleur, querySelectorAll returns a nodeList not an Array. You can't use Array methods on a nodeList you first need to convert it into an Array. Array.prototype.slice.call(document.querySelectorAll('.text_blocks')); $.filter is different as it's a custom function designed to work on any collection.I'm not sure what your HTML structure is. You say you're working with divs not a list, but your jQuery is filtering a list?Anyway, I typed this out, maybe it'll help.http://jsfiddle.net/p5f7vjfu/
September 11, 201511 yr ^Ah! Well spotted. That would confuse me to because of the similarities between the two types of collections. Eg. they both have the .lenght property that we always use in loops. Speaking of querySelectorAll: If your elements just have a single class wouldn't getElementsByClassName (which would return the same nodelist) be faster? I remember when both these "selectors" was introduced I was warned about performance isues with both and it was recomended to use getElementsByTagName and filter out the class names in a loop. But that was a long time ago and I guess browser implementation for the "new" selectors have improved. What are your experience with performance for the different methods? EDIT: I guess jQuery and other libraries will choose the best method depending on what you pass as selector argument Edited September 11, 201511 yr by Nillervision
September 11, 201511 yr Yeah the node list is an array like object. As Wynn pointed out you can borrow functions from the Array prototype and pass in the node-list as the this argument: [].forEach.call(document.querySelectorAll('.text_blocks'), function(node) { // do stuff with each node }); It's pretty horrible to have to do this, I'm sure there's a good reason why node-lists and the arguments parameter are not true arrays but I'm not seeing it! Edited September 11, 201511 yr by rbrtsmith
September 11, 201511 yr Technically getElements... returns a HTMLCollection, while querySelector... returns a NodeList.What the differences are I'm not entirely sure, I usually end up converting them to an array anyway.But I find querySelector more 'one size fits all'.There will always be a slight performance hit when using anything that's newer, because most of the time one is just an abstraction of the other, such as Array.forEach vs a for loop. But the difference isn't noticeable unless you micro analyze with tools such as JSPerf.
September 11, 201511 yr Hm... Yet another collection. Like Robert said: it's difficult to see the reason why. At least the arrays you declare your self are the same type in JS though they can be in {object} notation or [squarebracket] notation, with key value pairs or numeric indexes, they would technically be the same type of object (with same methods) Or am I wrong? In some languages there are different type arrays eg. for fixed indexes. You can not push data into a C# Array because the number of indexes can only be set on creation. If you want to add to a collection must use ArrayList or a List. CRAZY @@fleur : Sorry for getting off topic here. Sometimes my mind just wanders off Edited September 11, 201511 yr by Nillervision
September 11, 201511 yr Author Wynn, awesome solution, million thanks, of cause, it works! I didn't think that filter can be replaced with ? operator, very elegant solution! PS. I tried to typing it not a one time. Because google blocked me (I don't know why!) and now i use internet from IE. Crasy day:) So.. i understand Niller very well, i have the same mind now because today i got so much problems at the same time and i don't know how live till tomorrow Hope i will PS1. And how much time i should wait when google return me ability to use Chrome again? I can't develop my app with IE! Edited September 11, 201511 yr by fleur
September 11, 201511 yr Author Robert, thank you for video! I like Mattias video very much too! PS2. Quote don't working in IE. Edited September 11, 201511 yr by fleur
September 11, 201511 yr ^Totally share @@fleur s gratitude. I'm so happy that the JS experts here at WDF are so helpful and willing to share their knowledge. As JavaScript is becomming more and more prominent in modern web development, it is really nice for an oldtimer like me to have someone that are so willing to answer my questions. So times things can go a bit fast though. But in the last few months I've learned the concepts of closures, @@rbrtsmith have finaly made me understand some of the advantages of Object.create() without constructers and without the new keyword, @@Lyndsey taught me event delegation and now I see this super slick aproach to replace my clumsy for loops. I love WDF Edited September 12, 201511 yr by Nillervision
Create an account or sign in to comment