Recreating the Photo Gallery Filter Using jQuery, Part 2

Free JavaScript & jQuery Tutorial

Follow along this in-depth tutorial to create a photo gallery in JavaScript and jQuery, covering topics like populating arrays, programming filters, enhancing user experience, and more.

This exercise is excerpted from Noble Desktop’s past JavaScript training materials. Noble Desktop now teaches JavaScript and the MERN Stack in our Full Stack Development Certificate. To learn current skills in web development, check out our coding bootcamps in NYC and live online.

Topics covered in this JavaScript & jQuery tutorial:

Populating a standard JavaScript array using jQuery, Using JavaScript to skip over the zero index, Hiding the photos, Testing the checkbox’s functionality, Programming the inclusive & exclusive filters, Rerunning the filter when the checkbox is toggled, Improving the user experience

Exercise Preview

ex prev gallery jquery 2

Exercise Overview

In this exercise, we’ll continue where the previous exercise left off, creating the photo gallery using jQuery. In the last exercise, we got the buttons in the nav to select/deselect when clicked. In this exercise, we’ll write the code to filter the photos.

Full-Stack Web Development Certificate: Live & Hands-on, In NYC or Online, 0% Financing, 1-on-1 Mentoring, Free Retake, Job Prep. Named a Top Bootcamp by Forbes, Fortune, & Time Out. Noble Desktop. Learn More.
  1. If you completed the previous exercise, gallery-with-jquery.html and gallery-with-js.html should still be open in your code editor, and you can skip the following sidebar. We recommend you finish the previous exercise (B5) before starting this one. If you haven’t finished it, do the following sidebar.

    If You Did Not Do the Previous Exercise (B5)

    1. Close any files you may have open.
    2. Go into Desktop > Class Files > yourname-JavaScript jQuery Class and open the Photo-Filter-jQuery-2 folder.
    3. Open gallery-with-jquery.html. This is the photo gallery that we’ll be editing with jQuery.
    4. Also open gallery-with-js.html from the Photo-Filter-jQuery-2 folder. This is the photo gallery that we completed in exercise 3D using JavaScript. We’ll use this as a reference.

Populating a Standard JavaScript Array Using jQuery

In the last exercise, we got the navigation elements working. We also created an empty array to store the selected photo data-filter attributes. Next we need to populate the array by cycling through, grabbing the data-filter attributes of each element, and putting the selected items into the array.

  1. To see which function we used to populate the array with standard JavaScript, go to gallery-with-js.html in your code editor and look around line 256.

  2. Switch to gallery-with-jquery.html. Around line 180, call the populateArray() function as shown in bold:

    $filterNav.on('click', function() {
       toggleCategory($(this));
       populateArray();
    });
    
  3. Refer back to gallery-with-js.html around lines 181–196 to check out the standard JavaScript version of the populateArray() function.

  4. In gallery-with-jquery.html around line 178, add the function as shown in bold:

    function deselectOthers(filterChoice) {
    

    Code Omitted To Save Space

    }
    
    function populateArray() {
    
    }
    
    $filterNav.on('click', function() {
    
  5. The first thing we need to do in the populateArray() function is take the selected array and reset it back to an empty array. Add same JavaScript code as before:

    function populateArray() {
       selectedArray = [];
    }
    
  6. Add an conditional statement to check if the All button is selected:

    function populateArray() {
       selectedArray = [];
       if($allButton.attr('data-selected') == 'yes') {
    
       } else {
    
       }
    }
    
  7. Next we want to go through every filter except for all, take their data-filter values, and push them onto the selected array. To see how we did this using standard JavaScript, go to gallery-with-js.html and find the for loop around lines 185–187.

    Earlier in the workbook, you learned that if you want to use a jQuery method such as click() to apply something to everything in a group of elements (e.g. all the buttons in the navigation), you don’t need to write a loop because jQuery automatically performs a implicit loop over all of the matched elements.

    Because selectedArray is not a jQuery object, we have to use a different approach. We can use the handy jQuery .each() method. You can think of this explicit loop as a less complicated version of JavaScript’s for loop.

  8. Add the each method inside the if statement around line 181 and also add a console.log() line (around line 187), so we can see exactly what the selectedArray looks like at this point:

    function populateArray() {
       selectedArray = [];
       if($allButton.attr('data-selected') == 'yes') {
          $filterNav.each(function() {
             selectedArray.push($(this).attr('data-filter'));
          });
       } else {
    
       }
       console.log(selectedArray);
    }
    
  9. Save the file.

  10. Preview index.html in Chrome to see what we have so far (we’ll use its DevTools).

  11. Open the Console by hitting Cmd–Opt–J (Mac) or Ctrl–Shift–J (Windows).

  12. Click the All button in the nav to deselect it. You should see [] print to the Console, indicating an empty array.

  13. Click the All button again to select it. In the Console, you should see all the filter values in the array: ["all", "animals", "buildings", "trees", "bw"]

Using JavaScript to Skip Over the Zero Index

The only problem is it also grabbed "all" which we don’t want because we don’t have an all class we can apply. How do we get rid of it? This is an example of the limitations of trying to use just jQuery; sometimes when you want to do something more advanced you’ll also need to use JavaScript.

  1. Leave gallery-with-jquery.html open in Chrome so we can come back to it later.

  2. Return to your code editor.

  3. In gallery-with-jquery.html look at the code inside the each() method around line 182 to see that it’s going through the entire array and grabbing all the filter choices. We don’t have a way to skip over the 0 index (which would be the first item)!

  4. Let’s try using the native JavaScript shift() method to skip over the All selector and shift the other values. Around line 185, add the following bold code:

    if($allButton.attr('data-selected') == 'yes') {
       $filterNav.each(function() {
          selectedArray.push($(this).attr('data-filter'));
       });
       selectedArray.shift();
    } else {
    

    NOTE: The shift() method deletes the first item in the Array and “shifts” the other values so that 1 becomes 0, 2 becomes 1, etc.

  5. Save the file.

  6. Go to Chrome and reload gallery-with-jquery.html.

  7. Open the Console if it’s not already open.

  8. Click the All button in the nav to deselect it. As before, you should see [] print to the Console, indicating an empty array.

  9. Click the All button again to select it. In the Console, you should see all the array’s filter values, minus "all": ["animals", "buildings", "trees", "bw"]

Selecting Buttons Other than the All Button

In the case that a user clicks on any filter button other than the All selector, we want to run through the filters again, but this time we only want to push to the array if the data-selected attribute is set to "yes".

  1. Return to your code editor.

  2. Add the following bold code inside the else statement starting around line 186:

    } else {
       $filterNav.each(function() {
          if($(this).attr('data-selected') == 'yes') {
             selectedArray.push($(this).attr('data-filter'));
          }
       });
    }
    console.log(selectedArray);
    
  3. Save the file.

  4. Go to Chrome and reload gallery-with-jquery.html.

  5. Open the Console if it’s not already open.

  6. Click any of the filter buttons besides All and you should see the filter values appear in the Console. Great, the array is being populated successfully!

Hiding the Photos

  1. Switch back to your code editor.

  2. Still in gallery-with-jquery.html, call the filterPhotos() function around line 198:

    $filterNav.on('click', function() {
       toggleSelector($(this));
       populateArray();
       filterPhotos();
    });
    
  3. Around line 192, delete the console.log(selectedArray); line as well as any leftover whitespace.

  4. Around line 194, declare the filterPhotos() function as shown in bold:

    }
    
    function filterPhotos() {
    
    }
    
    $filterNav.on('click', function() {
    
  5. Refer back to gallery-with-js.html (around line 237 near the beginning of the filterPhotos() function) to see that the first thing we did in this function was hide all the photos.

  6. First let’s call the function to hide the photos. Back in gallery-with-jquery.html, add the following code in bold:

    function filterPhotos() {
       hideAllPics();
    }
    
  7. We need to declare this actual function. Above the filterPhotos() function, around line 194, add the following code in bold:

    function hideAllPics() {
    
    }
    
    function filterPhotos() {
    
  8. In gallery-with-js.html, look around lines 199–202 to see that the hideAllPics() function contains a loop that says to take all the imageContainers (the divs with the gallery class) and set them to display = 'none'.

  9. Because we are referencing these divs using jQuery, we can simply use either jQuery’s hide() or css() method and jQuery will perform an implicit loop. In gallery-with-jquery.html around line 195, add the bold code shown below:

    function hideAllPics() {
       $imageContainers.hide();
    }
    

    NOTE: Instead of .hide(); we could have used .css('display', 'none');

  10. Save the file.

  11. Go to Chrome and reload gallery-with-jquery.html.

  12. Click any of the filter buttons and you should see all the images disappear… It’s working so far!

Testing the Checkbox’s Functionality

Next we need to get the checkbox to filter exclusively (if checked) or filter inclusively (if not checked). Let’s test the functionality in the JavaScript Console.

  1. Switch back to your code editor.

  2. In the filterPhotos() function, add the following bold code around line 200:

    function filterPhotos() {
       hideAllPics();
       if($exclusive.is(':checked')) {
          console.log('checked');
       } else {
          console.log('not checked');
       }
    }
    

    NOTE: :checked is a pseudo-class, like :hover.

  3. Save the file.

  4. Let’s test if this is working. Go to Chrome and reload the page.

  5. Make sure the Console is open.

  6. Click one of the filter buttons and you should see not checked print to the Console because the checkbox is not checked by default.

  7. Check on the checkbox, then click one of the filter buttons. You should see checked print to the Console. Cool, it’s working as expected!

Programming the Inclusive Filter

Let’s start by creating the inclusive filter (for searches that include any filter).

  1. Back in your code editor, delete the console.log() s around lines 207 and 209.

  2. In the else statement around line 209, call the function we’re about to write:

    function filterPhotos() {
       hideAllPics();
       if($exclusive.is(':checked')) {
    
       } else {
          filterInclusive();
       }
    }
    
  3. Declare the actual function around line 198, between the hideAllPics() and filterPhotos() functions:

    }
    
    function filterInclusive() {
    
    }
    
    function filterPhotos() {
    
  4. Look back at gallery-with-js.html to check out the filterInclusive() function around lines 213–221. This is what we did:

    • First we created a variable called group.
    • Then we cycled through the selectedArray using a for loop.
    • If the condition is met, JavaScript takes everything inside the selectedArray, attaches a '.' to make it a class, puts it into the querySelectorAll() method, and saves that to the group variable.
    • Finally, the other loop sets the group’s display property to inline-block.
  5. We need to run through the values in the selectedArray and apply a function to them. It sounds like it would make sense to use the .each() method, but it won’t work as expected. In gallery-with-jquery.html, add the bold code around line 199 to see what happens:

    function filterInclusive() {
       selectedArray.each(function() {
          console.log('hello');
       });
    }
    
  6. Save the file.

  7. Go to Chrome and reload the page.

  8. Make sure the Console is open, then click on a filter button in the nav. In the Console, you’ll see an error: selectedArray.each is not a function.

    The problem is that selectedArray is not a jQuery object. While we normally can’t call jQuery functions on non-jQuery objects, there is a way around this.

  9. Let’s figure this out. In a new browser tab or window, go to: api.jquery.com

  10. In the search bar towards the top right, search for: $.each

  11. In the results, click on jQuery.each() (this is the same as $.each()—remember that $ is an alias for jQuery).

    This function allows you to call jQuery and attach a non-jQuery array as the first argument. For the second argument, you put the callback or function you want to apply to the array.

  12. Switch back to your code editor.

  13. Delete the selectedArray.each() function (around lines 199–201):

    selectedArray.each(function() {
       console.log('hello');
    });
    
  14. We want to pass in a function that we’ll apply to each item in the array. Replace the deleted code with the jQuery.each() method that includes multiple arguments:

    function filterInclusive() {
       $.each(selectedArray, function(i) {
    
       });
    }
    

    NOTE: The function takes a counter variable called i as an argument. We are passing it in as an index for whatever we’re cycling through in the selectedArray.

  15. Around line 200, add the following bold code:

    function filterInclusive() {
       $.each(selectedArray, function(i) {
          $('.' + selectedArray[i]).show();
       });
    }
    

    NOTE: We’re using the jQuery .each() method to pass in the selectedArray (a non-jQuery object) and perform the function on it (where we’ll be using the index of whatever we’re cycling through). Then we add the '.' to add a class selector onto the results, add the selectedArray value, and show the appropriate photos.

  16. Save the file.

  17. Go to Chrome and reload the page.

  18. Click the Black & White button (you could click any, but it’s easiest to spot the effect). You should see just the black and white photos filter.

  19. Click Trees and you’ll see photos that are either black & white OR have trees.

Programming the Exclusive Filter

  1. Switch back to your code editor.

  2. In the filterPhotos() function, around line 204, specify the following bold functionality that will run if the $exclusive checkbox is checked:

    function filterPhotos() {
       hideAllPics();
       if($exclusive.is(':checked')) {
          filterExclusive();
       } else {
          filterInclusive();
       }
    }
    
  3. Around line 204, between the filterInclusive() and filterPhotos() functions, declare the filterExclusive() function as shown in bold:

    }
    
    function filterExclusive() {
    
    }
    
    function filterPhotos() {
    
  4. Look back at gallery-with-js.html to check out the filterExclusive() function around lines 223–235 to see what we did in the standard JavaScript version.

    We put together a queryString and cycled through everything in the array. Then we took everything out of the array and added it to the queryString. Once we had a queryString (that wasn’t empty), we set it to display inline-block. Fortunately, jQuery’s going to help us simply this significantly.

  5. Back in gallery-with-jquery.html, around line 205, declare the queryString variable and set it to be an empty string:

    function filterExclusive() {
       var queryString = '';
    }
    
  6. We need to cycle through the array and add it to the queryString. To do that, we’ll use the .each() method again. Around line 206, add:

    function filterExclusive() {
       var queryString = '';
       $.each(selectedArray, function(i) {
          queryString += ('.' + selectedArray[i]);
       });
       console.log(queryString);
    }
    
  7. Save the file.

  8. Go to Chrome and reload the page. Make sure the Console is open.

  9. Check on the checkbox under the nav.

  10. Click the Trees button. You should see .trees print to the Console.

  11. Click the Buildings button. You should see .buildings.trees print to the Console.

  12. Click the All button and you’ll see .animals.buildings.trees.bw print to the Console. Great, the correct classes are being selected.

  13. Back in your code editor, around line 209, replace console.log(queryString); with the following bold if statement:

    function filterExclusive() {
       var queryString = '';
       $.each(selectedArray, function(i) {
          queryString += ('.' + selectedArray[i]);
       });
       if(queryString) {
          $(queryString).show();
       }
    }
    
  14. Save the file, go to Chrome, and reload the page.

  15. Check on the checkbox under the nav.

  16. Click the Animals and Black & White buttons. Now only black & white photos with animals are showing!

Rerunning the Filter When the Checkbox Is Toggled

  1. Now we need to specify what will happen whenever the checkbox is checked or unchecked (toggled on or off). The process will be pretty similar to how we did it with JavaScript. Return to gallery-with-jquery.html in your code editor.

  2. Below the end of the filterPhotos() function, around line 223, add:

    }
    
    $exclusive.on('change', function() {
       populateArray();
       filterPhotos();
    });
    
    $filterNav.on('click', function() {
    
  3. Save the file, go to Chrome, and reload the page.

  4. Click any two filter buttons in the nav.

  5. Check on the checkbox. Exclusive filtering should turn on.

  6. Uncheck the checkbox. It should start inclusive filtering.

Improving the User Experience

The finished photo filter page works wonderfully unless a user deselects all buttons. Let’s fix this.

  1. Switch back to your code editor.

  2. We’ll need to create a function that will address the issue. Around line 223, add the following function:

    }
    
    function noFilterSelection() {
    
    }
    
    $exclusive.on('change', function() {
    
  3. All we need to do is check to see if selectedArray is empty. If it’s empty, we can just assume they meant to “start again” with all the photos showing:

    function noFilterSelection() {
        if(selectedArray.length == 0) {
          $imageContainers.show();
        }
    }
    
  4. We will also want the All button to highlight, to let the users know what’s going on. Add the following:

    function noFilterSelection() {
       if(selectedArray.length == 0) {
          $imageContainers.show();
          $allButton.attr('data-selected', 'yes');
        }
    }
    
  5. Finally, we’ll need to call this function. Around line 216, call the function inside the filterPhotos() function, as follows:

    function filterPhotos() {
       hideAllPics();
       noFilterSelection();
       if($exclusive.is(':checked')) {
          filterExclusive();
       } else {
          filterInclusive();
       }
    }
    
  6. Save the file.

  7. Return to gallery-with-jquery.html in Chrome and reload the page. Deselect all filter buttons. Perfect!

    So in summary, we were able to redo the photo gallery in jQuery and it was simpler and faster and required less code.

    NOTE: If you want to refer to our final code example, go to Desktop > Class Files > yourname-JavaScript jQuery Class > Done-Files > Photo-Filter-jQuery-2.

photo of Dan Rodney

Dan Rodney

Dan Rodney has been a designer and web developer for over 20 years. He creates coursework for Noble Desktop and teaches classes. In his spare time Dan also writes scripts for InDesign (Make Book JacketProper Fraction Pro, and more). Dan teaches just about anything web, video, or print related: HTML, CSS, JavaScript, Figma, Adobe XD, After Effects, Premiere Pro, Photoshop, Illustrator, InDesign, and more.

More articles by Dan Rodney

How to Learn Coding

Master coding with hands-on training. Learning how to code in JavaScript, Python, and other popular languages can pave the way to a job in tech, such as web development, data science & analytics, or software engineering.

Yelp Facebook LinkedIn YouTube Twitter Instagram