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

Real-Time Filtering Search Box

Hello everyone!

Having some trouble trying to figure out how this would work.

I'm working on a project and i have a ul with list items which are images, and a search box on the top like below:

<div class="filter-container">
  <form action="#" method="#">
    <input type="search" id="filter" name="user_search">
  </form>
</div>

<div class="container">
  <ul class="photoGallery">
    <li><a href="#"><img src="#" alt="#" title="#"></a></li>
    <li><a href="#"><img src="#" alt="#" title="#"></a></li>
    <li><a href="#"><img src="#" alt="#" title="#"></a></li>
  </ul>
</div>

I want to be able to filter the list items in real time by the title attribute. Is there anyway to do this in JavaScript/jQuery? i'd rather code it myself than use a plugin. A big thank you in advance for replying!

3 Answers

First off, kudos for trying to figure out how things work rather than searching for a plugin! Let's try and plan out a solution.

Probably, you'll want to trigger filtering when typing occurs. Start here: http://api.jquery.com/keyup/ See if you can make an alert appear whenever you type a character in the input. That code will frame the rest of your solution.

Next, you want to match the value in the input with all of the titles. Sounds like you'll need to use a loop or jQuery's .each. See if you can add to your code above and console.log the title attibute for each img, whenever the keyup method runs.

Finally, you'll want to "filter" if the two values match. There are a few ways you could do this, but probably you'll just show and hide the imgs rather than modifying the markup (else it will be hard to make images re-appear after they've been deleted). Look up jQuery's .show and .hide -- if you've made it this far, it should be rather straightforward!

Be sure to post back when you're done or if you run into any problems.

First of all, Thanks for the reply. I got the alert box to appear when you type a character with no problem. Also, i got the title attribute to log when you type in the search field.

The last part however, i used an If/else statement to hide the images if the values didn't match and vise versa, and as soon as you type, all the images just hide. The if/else statement is inside the each() anonymous function, and i'm not sure if you'd want to call another each() method inside that code block instead of using that conditional statement.

Sorry if that's confusing. I'll post my code below for reference.

$( $search ).keyup( function () {
  var $title = $( "img" ).attr( "title" );
  $( ".photoGallery img" ).each( function () {
    console.log( $title );
    if ( $title === $search.val() ) {
      $( ".photoGallery img" ).show( "slow" );
    } else {
      $( ".photoGallery img" ).hide( "slow" );
    };
  } );
} );

The $search variable is equal to the input's ID.

Admittedly this is something I didn't think of.

I think you could try using a substring instead of direct ===

Try using indexOf actually

I dug through the web alittle more and found this code:

$(document).ready(function(){
    $search.keyup(function(){

        // Retrieve the input field text
        var filter = $(this).val();

        // Loop through the comment list
        $(".photoGallery img").each(function(){

            // If the list item does not contain the title attr, fade it out
            if ($(this).attr("title").search(new RegExp(filter, "i")) < 0) {
                $(this).fadeOut();

            // Show the list item if the phrase matches
            } else {
                $(this).fadeIn();
            }
        });
    });
});

This works, but does some weird things to the document when the list items filter. It looks like below the images, it just cuts the page off. All you can see is whitespace. Not sure what's causing that. Could be because the container isn't fixed.

I'm not sure why that would be. If the items are appearing and disappearing where they are supposed to, then I guess the JS is doing it's job. You can try playing around with clearfixes and stuff and see if you can solve what's going on below.