Match words in any order in Isotope (using input value)
Asked Answered
C

2

6

I'm using Isotope.js with vanilla javascript.

Inside my items, I have put a div with a display:none to hide keywords for each item. For example, the item Orange has the keywords 'color' and 'fruit'. So if someone types in any of those three words into the input form (orange, color, or fruit) that item will be shown via Isotope.

Here is a jsfiddle showing my project.

What I'm wanting to do, is if someone were to type all three words into the input form in any order the item will show. Right now the item will only show if the keywords are typed in order. For example, typing in "fruit color" will show the item Orange, but "color fruit" will not.

Edit: This answer here does exactly what I'm trying to achieve. I applied it to a jQuery version of my project and worked perfectly. However, I'm having troubling rewriting it in vanilla JS. Any help is immensely appreciated.

Ceraceous answered 24/11, 2020 at 7:12 Comment(0)
C
2

I ended up getting it working myself. I apologise, I'm still new to Javascript and am learning by trial and error, and I'm not sure how to give a proper explanation on how I got it working. But here is the final result:

var qsRegex;
var quicksearch = document.querySelector('input[type="text"]');

// init Isotope
var iso = new Isotope('#grid', {
  itemSelector: '.item',
  layoutMode: 'fitRows',
  transitionDuration: 1000,
  filter: function(itemElem) {
      var qsRegex = [];
      var resultRegex = [];
      var endResult = new Boolean();
      var searchID = quicksearch.value;
      var searchTable = searchID.split(" ");
      for (var i = 0; i < searchTable.length; i++) {
        qsRegex[i] = new RegExp("(^|\\s)(" + searchTable[i] + ")", 'gi');
        resultRegex[i] = qsRegex[i] ? itemElem.textContent.match(qsRegex[i]) : true;
        endResult = endResult && resultRegex[i];
      }
      return endResult;
  }
});


// use value of input to filter
var quicksearch = document.querySelector('input[type="text"]');
quicksearch.addEventListener('input', function() {

  
  iso.arrange();


});

Updated jsfiddle link

Ceraceous answered 30/11, 2020 at 9:13 Comment(0)
M
2

Can you try changing the following, I have removed the regex to string

filter: function(itemElem) {
    return qsRegex ? itemElem.textContent.indexOf(qsRegex) !== -1 : true;
}

var quicksearch = document.querySelector('input[type="text"]');
quicksearch.addEventListener('input', function() {
     // match items by first letter only
     qsRegex = quicksearch.value; // Changed here
     iso.arrange();
});
Moustache answered 30/11, 2020 at 4:28 Comment(1)
Thank you but this didn't make any differenceCeraceous
C
2

I ended up getting it working myself. I apologise, I'm still new to Javascript and am learning by trial and error, and I'm not sure how to give a proper explanation on how I got it working. But here is the final result:

var qsRegex;
var quicksearch = document.querySelector('input[type="text"]');

// init Isotope
var iso = new Isotope('#grid', {
  itemSelector: '.item',
  layoutMode: 'fitRows',
  transitionDuration: 1000,
  filter: function(itemElem) {
      var qsRegex = [];
      var resultRegex = [];
      var endResult = new Boolean();
      var searchID = quicksearch.value;
      var searchTable = searchID.split(" ");
      for (var i = 0; i < searchTable.length; i++) {
        qsRegex[i] = new RegExp("(^|\\s)(" + searchTable[i] + ")", 'gi');
        resultRegex[i] = qsRegex[i] ? itemElem.textContent.match(qsRegex[i]) : true;
        endResult = endResult && resultRegex[i];
      }
      return endResult;
  }
});


// use value of input to filter
var quicksearch = document.querySelector('input[type="text"]');
quicksearch.addEventListener('input', function() {

  
  iso.arrange();


});

Updated jsfiddle link

Ceraceous answered 30/11, 2020 at 9:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.