Guest Filtering
Relevant source files
The following files were used as context for generating this wiki page:The Guest Filtering feature is a key component of the enhanced search functionality within the "Jokes" section of the Norm Macdonald Archive redesign. It allows users to refine the list of jokes by selecting a specific guest from a dropdown menu. This filtering is performed client-side and works in conjunction with the text search to provide a powerful way for users to navigate the joke collection.
The feature is implemented in pure JavaScript and is central to improving the user experience on the jokes page. A similar guest filter is also present in the alternate codex-design prototype.
Sources: README.md:14, redesign/README.md:14, redesign/script.js, codex-design/index.html:48-51
Architecture and State Management
The filtering mechanism relies on a global state object that manages the application's data and user selections. The guest filter specifically interacts with the selectedGuest property.
Sources: redesign/script.js:5-14
State Properties
The following properties in the state object are crucial for the guest filtering functionality:
| Property | Type | Description |
|---|---|---|
jokes | Array | The full, unfiltered list of all jokes loaded from jokes-data.json. |
filteredJokes | Array | The list of jokes after all filters (search and guest) have been applied. |
selectedGuest | String | Stores the value of the currently selected guest from the dropdown. Empty string for "All Guests". |
Sources: redesign/script.js:6-12
This diagram illustrates the relevant parts of the application's state.
Sources: redesign/script.js:5-14
UI Components
The user interacts with the guest filter via a standard HTML <select> element located within the "Search and Filters" control section of the page.
Sources: redesign/jokes.html:120-129
HTML Structure
The filter is defined in redesign/jokes.html with the ID guest-filter. It is initially populated with a default "All Guests" option.
<div class="filter-box">
<label for="guest-filter" class="filter-label">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
<circle cx="12" cy="7" r="4"></circle>
</svg>
Guest:
</label>
<select id="guest-filter" class="filter-select">
<option value="">All Guests</option>
</select>
</div>
Sources: redesign/jokes.html:120-132
An alternative implementation with a similar structure can be found in the codex-design prototype.
Sources: codex-design/index.html:48-51
Data Flow and Logic
The guest filtering process involves three main steps: populating the filter with guest names, listening for user input, and applying the filter to the joke data.
1. Filter Population
Upon application initialization, after the main joke data is loaded, the guest filter dropdown is dynamically populated with a unique, sorted list of all guests found in the dataset.
This diagram shows the flow of the populateGuestFilter function.
Sources: redesign/script.js:84-95
The populateGuestFilter function is responsible for this logic.
function populateGuestFilter() {
const guestFilter = document.getElementById('guest-filter');
const guests = [...new Set(state.jokes.map(joke => joke.guest).filter(g => g))].sort();
guests.forEach(guest => {
const option = document.createElement('option');
option.value = guest;
option.textContent = guest;
guestFilter.appendChild(option);
});
}
Sources: redesign/script.js:84-95
2. Event Handling
An event listener is attached to the #guest-filter element's change event. When a user selects a different guest, this listener updates the state.selectedGuest property and then triggers the applyFilters function to re-filter and re-render the joke list.
// in initEventListeners()
const guestFilter = document.getElementById('guest-filter');
guestFilter.addEventListener('change', (e) => {
state.selectedGuest = e.target.value;
applyFilters();
});
Sources: redesign/script.js:512-516
3. Filtering Logic
The core filtering logic resides in the applyFilters function. It filters the master state.jokes array based on both the search term and the selected guest. The guest filter logic specifically checks if state.selectedGuest is empty (meaning "All Guests") or if the joke's guest property matches the selected guest.
function applyFilters() {
state.filteredJokes = state.jokes.filter(joke => {
const matchesSearch = joke.joke.toLowerCase().includes(state.searchTerm.toLowerCase()) ||
joke.guest?.toLowerCase().includes(state.searchTerm.toLowerCase()) ||
joke.episode?.toLowerCase().includes(state.searchTerm.toLowerCase());
const matchesGuest = !state.selectedGuest || joke.guest === state.selectedGuest;
return matchesSearch && matchesGuest;
});
state.currentPage = 1;
updateFilteredCount();
renderJokes();
renderPagination();
}
Sources: redesign/script.js:99-116
User Interaction Sequence
The following sequence diagram illustrates the complete flow from user interaction to the UI update.
Sources: redesign/script.js:99-116, 512-516
Summary
The Guest Filtering feature is a client-side enhancement that significantly improves the browsability of the joke archive. It is implemented using vanilla JavaScript, dynamically populating a dropdown from the source data and using a central state object to manage the user's selection. The filtering logic is efficient, combining the guest selection with a text search to provide a responsive and intuitive user experience.
Sources: README.md:14, redesign/script.js