Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Looping through element's attributes and comparing.

I'm looking to loop through a few things and make comparisons against a string I have saved in a variable. Everything will be lowercase to make the comparisons easy.

I have a photo gallery with data-title attributes that contain captions for each image. The alt attribute contains the image title. There are 12 images total (so 12 data-titles and 12 alt attributes).

I then have a search bar where a user inputs a word or a string. This input is saved to a string that I'll compare against.

How would I go about looping through the entire gallery making the comparisons against all of the attributes?

My user input is captured here

$(function() {

  // Variables
  var searchInput;

  // User's Search Input
  $('#searchInput').on('keyup change', function(){
    searchInput = this.value.toLowerCase();      
  });

});

but I'm unsure where to go next. Here's a sample html snippet of the image markup.

      <div class="gallery-item">
        <a href="assets/img/photos/01.jpg" data-lightbox="gallery" data-title="I love hay bales. Took this snap on a drive through the countryside past some straw fields.">
          <img src="assets/img/thumbnails/01.jpg" alt="Hay Bales">
        </a>
      </div>

And I want to see if anything from searchInput matches anything in the data-title or the alt attributes.

1 Answer

Hi Chris,

I made a rough version of this that works, but is not robust.

Instead of grabbing the items from the DOM before filtering them, I stored the objects in a JavaScript array of objects with the various fields. These objects are then rendered to the page on initialization and after clicking Search Now.

The main part of the code that you might be interested in is this function:

  var filterGallery = function filterGallery(searchTerms, currentArray) {
    var search = RegExp(searchTerms);
    var filteredArray = currentArray.filter(function(item) {
      return search.test(item.title);
    });
    return filteredArray;
  };

This function takes in the searchTerms variable that you had set, as well as the aforementioned array of objects that hold the values for the gallery items we render to the page.

The first line of the function constructs a regular expression using the current searchTerms that we can test the gallery item titles against.

Then I use the array filter method, which goes through each item in the gallery items array and checks to see if the search regular expression exists in the item's title. (if the test passes, it returns true which means that gallery item will be included in the filtered items).

The last line of the function returns those filtered items, which will then be rendered to the page.

Here is the complete code.

HTML:

<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>

  <input type="text" id="searchInput">
  <button id="searchNow">Search Now</button>

  <div id="root"></div>

</body>
</html>

JavaScript:

$(function() {

  // Variables
  var searchInput;
  var searchButton = document.querySelector('#searchNow');
  var galleryHolder = document.querySelector('#root');
  var galleryArray = [
    {
      title: 'i like haybales',
      link: 'someline',
      imgSrc: 'some source',
      alt: 'Haybales picture'
    },
    {
      title: 'i like kazoos',
      link: 'anotherlink',
      imgSrc: 'another source',
      alt: 'Kazoos picture'
    }
  ];

  // User's Search Input
  $('#searchInput').on(
  'keyup change', 
  function(){
    searchInput = this.value.toLowerCase();

  });

  $(searchButton).on('click', function() {
    var filteredGallery = filterGallery(searchInput, galleryArray);
    render(filteredGallery, galleryHolder);
  });

  var filterGallery = function filterGallery(searchTerms, currentArray) {
    var search = RegExp(searchTerms);
    var filteredArray = currentArray.filter(function(item) {
      return search.test(item.title);
    });
    return filteredArray;
  };


  var render = function render(array, parentNode) {
    var nodesToRender = [];
    array.forEach(function(item) {
      var div = document.createElement('DIV');
      var title = document.createElement('H1');
      var anchor = document.createElement('A');
      var img = document.createElement('IMG');

      anchor.href = item.link;
      img.src = item.imgSrc;
      img.alt = item.alt;
      title.innerHTML = item.title;

      anchor.appendChild(img);
      div.appendChild(title);
      div.appendChild(anchor);

      nodesToRender.push(div);
    });

    parentNode.innerHTML = '';

    nodesToRender.forEach(function(node) {
      parentNode.appendChild(node);
    });
  };

  render(galleryArray, galleryHolder);
});

Thank you Matt! This has helped me tremendously.

Sure thing, glad that it helped.