Overview
The Movie Nachos project includes two filter scripts that provide dropdown functionality for filtering and sorting content:
- movies-filters.js: Multi-filter system for movies (sort, genre, year)
- actors-filters.js: Single filter system for actors (sort only)
Movies Filters
Provides three separate filter dropdowns for the movies page.
DOM Elements
const filterSortBtn = document.getElementById('filter-sort');
const filterGenreBtn = document.getElementById('filter-genre');
const filterYearBtn = document.getElementById('filter-year');
const filterSortDropdown = document.getElementById('filter-sort-dropdown');
const filterGenreDropdown = document.getElementById('filter-genre-dropdown');
const filterYearDropdown = document.getElementById('filter-year-dropdown');
Filter Types
| Filter | Button ID | Dropdown ID | Purpose |
|---|
| Sort | filter-sort | filter-sort-dropdown | Sort movies by criteria |
| Genre | filter-genre | filter-genre-dropdown | Filter by movie genre |
| Year | filter-year | filter-year-dropdown | Filter by release year |
Sort Filter Toggle
filterSortBtn.addEventListener('click', function (e) {
e.preventDefault()
e.stopPropagation();
filterSortDropdown.style.display = "block";
filterGenreDropdown.style.display = "none";
filterYearDropdown.style.display = "none";
});
Clicking a filter button shows that dropdown while hiding the others, ensuring only one filter is open at a time.
Genre Filter Toggle
filterGenreBtn.addEventListener('click', function (e) {
e.preventDefault()
e.stopPropagation();
filterGenreDropdown.style.display = "block";
filterSortDropdown.style.display = "none";
filterYearDropdown.style.display = "none";
});
Year Filter Toggle
filterYearBtn.addEventListener('click', function (e) {
e.preventDefault()
e.stopPropagation();
filterYearDropdown.style.display = "block";
filterSortDropdown.style.display = "none";
filterGenreDropdown.style.display = "none";
});
Event Handling
Each filter button uses:
e.preventDefault(): Prevents default link/button behavior
e.stopPropagation(): Stops event from bubbling to parent elements
stopPropagation() prevents the document click listener from immediately closing the dropdown that was just opened.
Click-Outside to Close
Dropdowns automatically close when clicking outside:
document.addEventListener('click', function (e) {
if (!filterSortDropdown.contains(e.target)) filterSortDropdown.style.display = "none";
if (!filterGenreDropdown.contains(e.target)) filterGenreDropdown.style.display = "none";
if (!filterYearDropdown.contains(e.target)) filterYearDropdown.style.display = "none";
});
The contains() method checks if the click target is inside the dropdown element, preventing the dropdown from closing when clicking its own content.
Actors Filters
Simplified single-filter system for the actors page.
Implementation
document.addEventListener('DOMContentLoaded', function() {
// Toggle filter dropdown
const filterSortBtn = document.getElementById('filter-sort');
const filterSortDropdown = document.getElementById('filter-sort-dropdown');
filterSortBtn.addEventListener('click', function (e) {
e.preventDefault()
e.stopPropagation();
filterSortDropdown.style.display = "block";
});
// Close dropdown when click elsewhere
document.addEventListener('click', function (e) {
if (!filterSortDropdown.contains(e.target)) filterSortDropdown.style.display = "none";
});
});
Differences from Movies Filters
- Only has one filter (sort)
- No need to hide other dropdowns
- Same click-outside-to-close functionality
- Uses the same element IDs as movies filters
Both scripts use filter-sort as the button ID. Ensure these scripts are loaded on different pages to avoid ID conflicts.
Filter Dropdown Pattern
Both scripts follow a consistent pattern:
- Initialize on DOM ready: Wrap all code in
DOMContentLoaded event
- Get element references: Store button and dropdown elements
- Toggle on button click: Show dropdown and hide others
- Prevent event bubbling: Use
preventDefault() and stopPropagation()
- Close on outside click: Document-level click listener to close dropdowns
HTML Structure Expected
<!-- Filter buttons -->
<button id="filter-sort">Sort</button>
<button id="filter-genre">Genre</button>
<button id="filter-year">Year</button>
<!-- Filter dropdowns -->
<div id="filter-sort-dropdown" style="display: none;">
<!-- Sort options -->
</div>
<div id="filter-genre-dropdown" style="display: none;">
<!-- Genre options -->
</div>
<div id="filter-year-dropdown" style="display: none;">
<!-- Year options -->
</div>
Dropdowns should be hidden by default with display: none and will be shown by the JavaScript when needed.
Usage Examples
Movies Page
Include movies-filters.js for full filter functionality:
<script src="scripts/movies-filters.js"></script>
Actors Page
Include actors-filters.js for sort-only filtering:
<script src="scripts/actors-filters.js"></script>
- Movies filters:
scripts/movies-filters.js:1-41
- Actors filters:
scripts/actors-filters.js:1-17
Customization
To add more filters to the movies page:
- Create new button and dropdown elements with unique IDs
- Add references to the DOM elements
- Create click event listener following the existing pattern
- Add the new dropdown to the document click listener
- Update all filter button listeners to hide the new dropdown
// Example: Adding a rating filter
const filterRatingBtn = document.getElementById('filter-rating');
const filterRatingDropdown = document.getElementById('filter-rating-dropdown');
filterRatingBtn.addEventListener('click', function (e) {
e.preventDefault()
e.stopPropagation();
filterRatingDropdown.style.display = "block";
filterSortDropdown.style.display = "none";
filterGenreDropdown.style.display = "none";
filterYearDropdown.style.display = "none";
});