jQuery & DOM Manipulation

Filtering & Searching Elements

15 min Lesson 9 of 30

Understanding Element Filtering and Searching

After selecting elements with jQuery, you often need to narrow down or refine your selection. Filtering methods allow you to reduce a set of matched elements based on specific criteria, while searching methods help you find specific elements within your selection.

These methods are essential for building dynamic, interactive interfaces where you need precise control over which elements are affected by your code.

Why Filter and Search?

  • Precision: Target exactly the elements you need
  • Performance: Work with smaller sets of elements
  • Conditional logic: Apply different behaviors based on element properties
  • Dynamic selection: Adapt to changing page content
Note: Filtering methods reduce the current selection, while searching methods find new elements within the current selection. Understanding this distinction is key to mastering jQuery traversal.

The filter() Method

The filter() method reduces the set of matched elements to those that match a selector or pass a function test.

HTML: <ul class="products"> <li class="product" data-price="50">Product A</li> <li class="product" data-price="150">Product B</li> <li class="product sale" data-price="75">Product C</li> <li class="product" data-price="200">Product D</li> </ul> jQuery - Filter with Selector: // Get only products on sale $(".product").filter(".sale"); // Get products with specific attribute $(".product").filter("[data-price]"); jQuery - Filter with Function: // Get products under $100 $(".product").filter(function() { return $(this).data("price") < 100; }); // Get products with long names $(".product").filter(function() { return $(this).text().length > 10; }); // Apply discount to filtered products $(".product").filter(function() { return $(this).data("price") > 100; }).addClass("premium");
Tip: When using a function with filter(), return true to keep the element in the selection, or false to remove it.

The not() Method

The not() method is the opposite of filter() - it removes elements from the matched set that match a selector or function.

HTML: <div class="menu"> <a href="#" class="link active">Home</a> <a href="#" class="link">Products</a> <a href="#" class="link">About</a> <a href="#" class="link disabled">Contact</a> </div> jQuery - Not with Selector: // Get all links except the active one $(".link").not(".active"); // Get all links except disabled $(".link").not(".disabled"); // Get all except first and last $(".link").not(":first, :last"); jQuery - Not with Function: // Get all non-empty links $(".link").not(function() { return $(this).text().trim() === ""; }); // Remove hover effect from all except active $(".link").not(".active").removeClass("hover");

The has() Method

The has() method filters elements that contain at least one element matching a selector. It's perfect for parent-child filtering.

HTML: <div class="cards"> <div class="card"> <h3>Card 1</h3> <img src="image1.jpg"> </div> <div class="card"> <h3>Card 2</h3> <p>No image here</p> </div> <div class="card"> <h3>Card 3</h3> <img src="image3.jpg"> </div> </div> jQuery: // Get only cards that contain images $(".card").has("img"); // Add border to cards with images $(".card").has("img").css("border", "2px solid blue"); // Get list items that contain links $("li").has("a").addClass("has-link"); // Get sections that contain forms $("section").has("form").addClass("interactive");
Tip: has() is more efficient than using filter() with find() when you only need to check for the presence of descendant elements.

The is() Method

The is() method checks if at least one element in the set matches a selector. It returns true or false, not a jQuery object.

HTML: <div class="container"> <input type="checkbox" class="agree" checked> <button class="submit">Submit</button> </div> jQuery: // Check if checkbox is checked if ($(".agree").is(":checked")) { console.log("User agreed to terms"); } // Check if element is visible if ($(".modal").is(":visible")) { $(".modal").hide(); } // Check if element has a class if ($(".submit").is(".disabled")) { console.log("Button is disabled"); } // Check multiple conditions if ($(".element").is(":visible, :animated")) { console.log("Element is visible or animating"); } // Practical use in event handler $(".submit").on("click", function() { if ($(this).is(".disabled")) { return false; // Don't submit } // Submit form });
Important: is() returns a boolean (true/false), not a jQuery object. You cannot chain other jQuery methods after is().

The eq() Method

The eq() method reduces the matched set to the element at a specific index. Indexes are zero-based.

HTML: <ul class="list"> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> <li>Item 4</li> </ul> jQuery: // Get the first item (index 0) $("li").eq(0); // Get the third item (index 2) $("li").eq(2); // Get the last item (negative index) $("li").eq(-1); // Get the second-to-last item $("li").eq(-2); // Highlight the third item $("li").eq(2).addClass("highlight"); // Remove the second item $("li").eq(1).remove();

The first() and last() Methods

Shortcuts for getting the first or last element in a matched set.

HTML: <div class="gallery"> <img src="photo1.jpg"> <img src="photo2.jpg"> <img src="photo3.jpg"> </div> jQuery: // Get first image (same as eq(0)) $("img").first(); // Get last image (same as eq(-1)) $("img").last(); // Add border to first and last $("img").first().css("border-left", "3px solid red"); $("img").last().css("border-right", "3px solid red"); // Remove first item from list $(".list li").first().remove();

The slice() Method

The slice() method reduces the set to a subset specified by a range of indices.

HTML: <ul class="items"> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> <li>Item 4</li> <li>Item 5</li> </ul> jQuery: // Get items 2, 3, and 4 (indexes 1, 2, 3) $("li").slice(1, 4); // Get all items from index 2 onwards $("li").slice(2); // Get items from the end $("li").slice(-3); // Last 3 items // Hide the middle items $("li").slice(1, -1).hide(); // Style a range of items $("li").slice(1, 3).css("background", "yellow");

The each() Method

The each() method iterates over each element in the matched set, executing a function for each one.

HTML: <div class="products"> <div class="product" data-id="101">Product A</div> <div class="product" data-id="102">Product B</div> <div class="product" data-id="103">Product C</div> </div> jQuery: // Log each product ID $(".product").each(function(index, element) { console.log("Index: " + index); console.log("ID: " + $(element).data("id")); }); // Add index number to each item $(".product").each(function(index) { $(this).prepend("<span>" + (index + 1) + ". </span>"); }); // Different style for odd/even items $(".product").each(function(index) { if (index % 2 === 0) { $(this).addClass("even"); } else { $(this).addClass("odd"); } }); // Stop iteration early $(".product").each(function(index) { if ($(this).data("id") === 102) { return false; // Stop iterating } console.log("Processing: " + $(this).text()); });
Tip: Inside each(), this refers to the raw DOM element. Use $(this) to convert it to a jQuery object and access jQuery methods.

The map() Method

The map() method passes each element through a function and returns a new jQuery object containing the returned values.

HTML: <ul class="fruits"> <li data-price="2.50">Apple</li> <li data-price="1.75">Banana</li> <li data-price="3.00">Orange</li> </ul> jQuery: // Get array of all prices var prices = $("li").map(function() { return $(this).data("price"); }).get(); // [2.50, 1.75, 3.00] // Get array of all fruit names var names = $("li").map(function() { return $(this).text(); }).get(); // Calculate total price var total = $("li").map(function() { return $(this).data("price"); }).get().reduce((sum, price) => sum + price, 0); console.log("Total: $" + total); // Total: $7.25

Practical Example: Advanced Product Filter

HTML: <div class="shop"> <div class="filters"> <select id="category-filter"> <option value="all">All Categories</option> <option value="electronics">Electronics</option> <option value="clothing">Clothing</option> </select> <input type="number" id="max-price" placeholder="Max price"> <input type="checkbox" id="sale-only"> Sale only </div> <div class="products"> <div class="product" data-category="electronics" data-price="999"> <h3>Laptop</h3> <p class="price">$999</p> </div> <div class="product sale" data-category="clothing" data-price="49"> <h3>Jacket</h3> <p class="price">$49</p> </div> <div class="product" data-category="electronics" data-price="699"> <h3>Phone</h3> <p class="price">$699</p> </div> </div> </div> jQuery: function filterProducts() { var category = $("#category-filter").val(); var maxPrice = parseFloat($("#max-price").val()) || Infinity; var saleOnly = $("#sale-only").is(":checked"); // Start with all products var $products = $(".product"); // Filter by category if (category !== "all") { $products = $products.filter("[data-category='" + category + "']"); } // Filter by price $products = $products.filter(function() { return $(this).data("price") <= maxPrice; }); // Filter by sale if (saleOnly) { $products = $products.filter(".sale"); } // Show filtered products, hide others $(".product").not($products).fadeOut(); $products.fadeIn(); // Show count console.log("Showing " + $products.length + " products"); } // Attach filter to inputs $("#category-filter, #max-price, #sale-only").on("change", filterProducts);

Practical Example: Table Row Filtering

HTML: <input type="text" id="search" placeholder="Search table..."> <table class="data-table"> <tr><td>John Doe</td><td>Developer</td><td>$80,000</td></tr> <tr><td>Jane Smith</td><td>Designer</td><td>$75,000</td></tr> <tr><td>Bob Johnson</td><td>Manager</td><td>$90,000</td></tr> </table> jQuery: $("#search").on("keyup", function() { var searchTerm = $(this).val().toLowerCase(); $(".data-table tr").filter(function() { var rowText = $(this).text().toLowerCase(); return rowText.indexOf(searchTerm) === -1; }).hide(); $(".data-table tr").filter(function() { var rowText = $(this).text().toLowerCase(); return rowText.indexOf(searchTerm) !== -1; }).show(); });

Practical Example: Form Validation

HTML: <form class="registration"> <input type="text" name="username" required> <input type="email" name="email" required> <input type="password" name="password" required> <input type="text" name="phone"> <button type="submit">Register</button> </form> jQuery: $(".registration").on("submit", function(e) { // Get all required fields var $required = $(this).find("input[required]"); // Filter empty fields var $empty = $required.filter(function() { return $(this).val().trim() === ""; }); if ($empty.length > 0) { e.preventDefault(); $empty.addClass("error"); alert($empty.length + " required fields are empty"); } // Validate email format var $email = $(this).find("input[type='email']"); if (!$email.filter(function() { var email = $(this).val(); return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); }).length) { e.preventDefault(); $email.addClass("error"); alert("Invalid email format"); } }); // Remove error on input $(".registration input").on("input", function() { $(this).removeClass("error"); });

Comparison Table

Method Returns Use Case
filter() jQuery object (reduced) Keep elements matching criteria
not() jQuery object (reduced) Remove elements matching criteria
has() jQuery object (reduced) Keep elements containing descendants
is() Boolean (true/false) Check if elements match selector
eq() jQuery object (1 element) Get element at specific index
first() / last() jQuery object (1 element) Get first or last element
slice() jQuery object (range) Get subset by index range
each() jQuery object (original) Iterate and perform actions
map() jQuery object (transformed) Transform elements to new values

Practice Exercise

Scenario: Build an employee directory with advanced filtering capabilities.

HTML Structure:
<div class="directory"> <div class="controls"> <input type="text" id="name-search" placeholder="Search by name"> <select id="department-filter"> <option value="all">All Departments</option> <option value="engineering">Engineering</option> <option value="design">Design</option> <option value="marketing">Marketing</option> </select> <input type="number" id="min-salary" placeholder="Min salary"> </div> <div class="employees"> <div class="employee" data-dept="engineering" data-salary="85000"> <h3>Alice Johnson</h3> <p>Senior Developer</p> </div> <div class="employee" data-dept="design" data-salary="70000"> <h3>Bob Smith</h3> <p>UI Designer</p> </div> <div class="employee" data-dept="engineering" data-salary="95000"> <h3>Charlie Brown</h3> <p>Tech Lead</p> </div> </div> </div>
Your Tasks:
  1. Filter employees by name (using filter() and text matching)
  2. Filter by department (using filter() with data attribute)
  3. Filter by minimum salary (using filter() with function)
  4. Combine all three filters together
  5. Display count of visible employees
  6. Bonus: Use map() to calculate average salary of visible employees
  7. Bonus: Highlight the first and last visible employee differently
  8. Bonus: Add "No results" message when no employees match
Hint: Chain multiple filter() calls or combine conditions in a single filter function.

Key Takeaways

  • filter() keeps matching elements, not() removes them
  • has() filters by descendant presence - great for parent-child logic
  • is() returns boolean - use for conditional checks, not chaining
  • eq(), first(), last(), slice() select by position
  • each() iterates for side effects, map() transforms to new values
  • Filter methods are chainable and can be combined for complex selection logic
  • Always use $(this) inside iteration callbacks to access jQuery methods

ES
Edrees Salih
16 hours ago

We are still cooking the magic in the way!