jeffkmeng
jeffkmeng

Reputation: 879

How to use javascript to filter a large list by html attribute value

I'm trying to make a reference guide for a mixture of many html icons. I have the following html code:

<input id="search" type="text" placeholder="Search Icons">
<input id="submit" type="button" value="Submit!">
<input id="cancel" type="button" value="Cancel">
<div id="icon-list">
    <li>
        <div class="icon icon-name"></div>
        <input type="text" readonly="readonly" value="name">
    </li>
    <li>
        <div class="icon icon-name2"></div>
        <input type="text" readonly="readonly" value="name2">
    </li>
    <li>
        <div class="icon icon-name3"></div>
        <input type="text" readonly="readonly" value="name3">
    </li>
    <!-- repeated 100 or more times -->
</div>

I'd like to be able to filter out the icons(<li>) based on the value attribute of the input inside it, preferably using fuzzy search. Is there a library or some code that can do this for me?

EDIT: I'd like to know mainly how to implement the search from the value of the value attribute, not how to implement the fuzzy search. Example:

Upvotes: 2

Views: 2121

Answers (1)

user01
user01

Reputation: 901

If all you're interested in is filtering the lis based on the value in the input, that can be done many, many ways. I threw something together with jQuery, but anything with a view layer, like React or Angular, could manage. Fuzzy searches aren't terribly well defined, but the Fuse.js does some kind of fuzzy search. I plugged it in.

For about a 100, you could probably get away with a similar implementation like below (there's a lot of efficiency that can be picked up with all the jQuery calls).

var liElements = $.makeArray($('#icon-list li').map(function(idx, elm) {
  var jElm = $(elm);
  var value = jElm.find('input').attr('value');
  return {
    jElm, value
  };
}));
var fuse = new Fuse(liElements, {
  keys: ["value"],
  threshold: 0.2
});

var search = $('#search');
var filter = function() {
  var target = search.val().trim();
  if (target.length < 1) {
    liElements.forEach(function(obj) {
      obj.jElm.show();
    });
    return;
  }
  var results = fuse.search(target);

  liElements.forEach(function(obj) {
    obj.jElm.hide();
  });
  results.forEach(function(obj) {
    obj.jElm.show();
  });
};


search.keyup(filter);
$('#submit').click(filter);
<script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/2.2.0/fuse.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="search" type="text" placeholder="Search Icons">
<input id="submit" type="button" value="Submit!">
<input id="cancel" type="button" value="Cancel">
<div id="icon-list">
  <li>
    <div class="icon icon-name"></div>
    <input type="text" readonly="readonly" value="teal">
  </li>
  <li>
    <div class="icon icon-name2"></div>
    <input type="text" readonly="readonly" value="mittens">
  </li>
  <li>
    <div class="icon icon-name3"></div>
    <input type="text" readonly="readonly" value="mittons">
  </li>
  <!-- repeated 100 or more times -->
</div>

Upvotes: 2

Related Questions