Filtering Data Client-Side: Comparing CSS, jQuery, and React | CSS-Tricks

Say you have a list of 100 names:

<ul>
  <li>Randy Hilpert</li>
  <li>Peggie Jacobi</li>
  <li>Ethelyn Nolan Sr.</li> 
  <!-- and then some -->
</ul>

...or file names, or phone numbers, or whatever. And you want to filter them client-side, meaning you aren't making a server-side request to search through data and return results. You just want to type "rand" and have it filter the list to include "Randy Hilpert" and "Danika Randall" because they both have that string of characters in them. Everything else isn't included in the results.

Let's look at how we might do that with different technologies.

CSS can sorta do it, with a little help.

CSS can't select things based on the content they contain, but it can select on attributes and the values of those attributes. So let's move the names into attributes as well.

<ul>
  <li data-name="Randy Hilpert">Randy Hilpert</li>
  <li data-name="Peggie Jacobi">Peggie Jacobi</li>
  <li data-name="Ethelyn Nolan Sr.">Ethelyn Nolan Sr.</li> 
  ...
</ul>

Now to filter that list for names that contain "rand", it's very easy:

li {
  display: none;
}
li[data-name*="rand" i] {
  display: list-item;
}

Note the i on Line 4. That means "case insensitive" which is very useful here.

To make this work dynamically with a filter <input>, we'll need to get JavaScript involved to not only react to the filter being typed in, but generate CSS that matches what is being searched.

Say we have a <style> block sitting on the page:

<style id="cssFilter">
  /* dynamically generated CSS will be put in here */
</style>

We can watch for changes on our filter input and generate that CSS:

filterElement.addEventListener("input", e => {
  let filter = e.target.value;
  let css = filter ? `
    li {
      display: none;
    }
    li[data-name*="${filter}" i] {
      display: list-item;
    }
  ` : ``;
  window.cssFilter.innerHTML = css;
});

Note that we're emptying out the style block when the filter is empty, so all results show.

See the Pen
Filtering Technique: CSS
[1] by Chris Coyier (@chriscoyier[2])
on CodePen[3].

I'll admit it's a smidge weird to leverage CSS for this, but Tim Carry once took it way further[4] if you're interested in the concept.

jQuery makes it even easier.

Since we need JavaScript anyway, perhaps jQuery is an acceptable tool. There are two notable changes here:

  • jQuery can select items based on the content they contain. It has a selector API just for this. We don't need the extra attribute anymore.
  • This keeps all the filtering to a single technology.

We still watch the input for typing, then if we have a filter term, we hide all the list items and reveal the ones that contain our filter term. Otherwise, we reveal them all again:

const listItems = $("li");

$("#filter").on("input", function() {
  let filter = $(this).val();
  if (filter) {
    listItems.hide();
    $(`li:contains('${filter}')`).show();
  } else {
    listItems.show();
  }
});

It's takes more fiddling to make the filter case-insensitive than CSS does, but we can do it by overriding the default method:

jQuery.expr[':'].contains = function(a, i, m) {
  return jQuery(a).text().toUpperCase()
      .indexOf(m[3].toUpperCase()) >= 0;
};

See the Pen
Filtering Technique: jQuery
[5] by Chris Coyier (@chriscoyier[6])
on CodePen[7].

React can do it with state and rendering only what it needs.

There is no one-true-way to do this in React, but I would think it's React-y to keep the list of names as data (like an Array), map over them, and only render what you need. Changes in the input filter the data itself and React re-renders as necessary.

If we have an names = [array, of, names], we can filter it pretty easily:

filteredNames = names.filter(name => {
  return name.includes(filter);
});

This time, case sensitivity can be done like this:

filteredNames = names.filter(name => {
  return name.toUpperCase().includes(filter.toUpperCase());
});

Then we'd do the typical .map() thing in JSX to loop over our array and output the names.

See the Pen
Filtering Technique: React
[8] by Chris Coyier (@chriscoyier[9])
on CodePen[10].

I don't have any particular preference

This isn't the kind of thing you choose a technology for. You do it in whatever technology you already have. I also don't think any one approach is particularly heavier than the rest in terms of technical debt.

References

  1. ^ Filtering Technique: CSS (codepen.io)
  2. ^ @chriscoyier (codepen.io)
  3. ^ CodePen (codepen.io)
  4. ^ once took it way further (stories.algolia.com)
  5. ^ Filtering Technique: jQuery (codepen.io)
  6. ^ @chriscoyier (codepen.io)
  7. ^ CodePen (codepen.io)
  8. ^ Filtering Technique: React (codepen.io)
  9. ^ @chriscoyier (codepen.io)
  10. ^ CodePen (codepen.io)
keywords

No Items Found.

Add Comment
Type in a Nick Name here
 
Other Items in webdev
Font Awesome Icons [ Icons ] - CSS Bundle Daily Dev Tips CSS Background Patterns by MagicPattern GitHub - ganlanyuan/tiny-slider: Vanilla javascript slider for all purposes. GitHub - jonasstrehle/supercookie: ⚠️ Browser fingerprinting via favicon! URL-encoder for SVG Bootstrap Icons · Official open source SVG icon library for Bootstrap GitHub - kognise/water.css: A drop-in collection of CSS styles to make simple websites just a little nicer Toggle light and dark themes in Bootstrap - DEV Deploy your Publish website for free on GitHub Pages - DEV Bootstrap · The most popular HTML, CSS, and JS library in the world. GitHub - diegocard/awesome-html5: A curated list of awesome HTML5 resources Fixing PHP SQLite database is locked warning - Unable to execute statement: database is locked [ php ] - KruXoR openstreetmap.org 50 Developer tools to make your life a little easier https://www.mrlacey.com/2020/07/youve-only-added-two-lines-why-did-that.html?m=1 GitHub - ForEvolve/bootstrap-dark: Bootstrap 4 dark theme that supports togging dark/light themes as well. There is no fluff, it changes the color of Bootstrap and that's it, no new thing to learn or unlearn, just Bootstrap, but Dark! Responsive Web Design Online Testing - isResponsive Trianglify.io · Low Poly Pattern Generator Grid.js - Advanced table plugin HEAD - A free guide to <head> elements Roots | Modern WordPress Development Tools A Local Dev Tool For Every Project | Lando new.css Synchronized responsive testing, development, inspection | Vanamco Gold Price Charts Widgets | GoldBroker.com Trianglify.io · Low Poly Pattern Generator Special tags that Google understands - Search Console Help 404 Error Page Codepen ScrollMagic ♥ Demo AOS - Animate on scroll library Font Awesome v4.7.0 - Icon Search Tool Carbon Offers — LowEndTalk Featherlight – The ultra slim jQuery lightbox. Tailwind CSS - A Utility-First CSS Framework for Rapidly Building Custom Designs HEAD - A free guide to <head> elements API Blueprint | API Blueprint Filtering Data Client-Side: Comparing CSS, jQuery, and React | CSS-Tricks CSS Quickies: CSS Variables - Or how you create a 🌞white/🌑dark theme easily - DEV Community 👩‍💻👨‍💻 Responsive Slider Timeline Colormind - the AI powered color palette generator Get Waves – Create SVG waves for your next design Nuxt.js - The Vue.js Framework CodeSandbox: Online Code Editor Tailored for Web Application Development Hover.css - A collection of CSS3 powered hover effects Live.js - One script closer to Designing in the Browser Color this sofa! – SVG + Blend Mode trick You Might Not Need jQuery CSS Wave Animation with a .png
Search Linx
Search Linx by entering your search text above.
Welcome

This is my test area for webdev. I keep a collection of code here, mostly for my reference. Also if i find a good link, i usually add it here and then forget about it. more...

Subscribe to weekly updates about things i have added to the site or thought interesting during the last week.

You could also follow me on twitter or not... does anyone even use twitter anymore?

If you found something useful or like my work, you can buy me a coffee here. Mmm Coffee. ☕

❤️👩‍💻🎮

🪦 2000 - 16 Oct 2022 - Boots
Random Quote


Random CSS Property

break-before

The break-before CSS property sets how page, column, or region breaks should behave before a generated box. If there is no generated box, the property is ignored.
break-before css reference