Filters
Web Development Courses
Explore courses from experienced, real-world experts.
React.js Complete Course - Curriculum Outline
{
if (input.value === '') {
input.checked = true; // Check 'All' options
} else {
input.checked = false; // Uncheck everything else
}
});
// Close offcanvas if open
const filtersOffcanvas = bootstrap.Offcanvas.getInstance(document.getElementById('filtersOffcanvas'));
if (filtersOffcanvas) {
filtersOffcanvas.hide();
}
// Force PJAX request
$.pjax({
container: '#search-results',
url: url.toString(),
push: false,
replace: false,
timeout: 10000
});
}
// Remove individual filter
function removeFilter(filterType, filterValue) {
console.log('Removing filter:', filterType, filterValue); // Debug log
const url = new URL(window.location);
if (filterType === 'features' && filterValue) {
// Remove specific feature
const features = url.searchParams.getAll('features[]');
const updatedFeatures = features.filter(f => f !== filterValue);
url.searchParams.delete('features[]');
updatedFeatures.forEach(f => url.searchParams.append('features[]', f));
// Update checkboxes
document.querySelectorAll('input[name="features[]"][value="' + filterValue + '"]').forEach(checkbox => {
checkbox.checked = false;
});
} else {
// Remove other filters
url.searchParams.delete(filterType);
// Update form inputs to 'All' option
document.querySelectorAll('input[name="' + filterType + '"]').forEach(input => {
if (input.value === '' || input.value === 'all') {
input.checked = true; // Check 'All' option
} else {
input.checked = false; // Uncheck others
}
});
}
// Force PJAX request
$.pjax({
container: '#search-results',
url: url.toString(),
push: false,
replace: false,
timeout: 10000
}).done(function() {
console.log('Filter removed successfully');
}).fail(function() {
console.log('PJAX failed, redirecting normally');
window.location.href = url.toString();
});
}
function preventFormSubmission() {
// Prevent all forms with data-pjax attribute from normal submission
$(document).on('submit', 'form[data-pjax]', function(e) {
e.preventDefault();
return false;
});
}
function initializeFilters() {
// Prevent form submissions
$(document).off('submit.preventform').on('submit.preventform', 'form[data-pjax]', function(e) {
e.preventDefault();
return false;
});
// Bind filter change events using event delegation
$(document).off('change.filters').on('change.filters', '.filter-checkbox, .filter-radio', function(e) {
e.preventDefault();
handleFilterChange();
});
// Bind clear all filter events
$(document).off('click.clearfilters').on('click.clearfilters', '#clearAllFiltersBtn, #clearAllFilters, .clear-all-filters, #clearAllFiltersOffcanvas', function(e) {
e.preventDefault();
e.stopPropagation();
console.log('Clear all filters clicked');
clearAllFilters();
return false;
});
// Bind remove individual filter events - FIXED
$(document).off('click.removefilter').on('click.removefilter', '.remove-filter', function(e) {
e.preventDefault();
e.stopPropagation();
const filterType = $(this).attr('data-filter') || $(this).data('filter');
const filterValue = $(this).attr('data-value') || $(this).data('value');
console.log('Remove filter button clicked:', filterType, filterValue);
removeFilter(filterType, filterValue);
return false;
});
// Filters button click handler
$(document).off('click.filtersbutton').on('click.filtersbutton', '#filtersButton', function(e) {
e.preventDefault();
e.stopPropagation();
console.log('Filters button clicked');
return false;
});
// Show more/less functionality
$(document).off('click.showmore').on('click.showmore', '[data-bs-toggle="collapse"]', function(e) {
e.stopPropagation();
const button = $(this);
const showMore = button.find('.show-more');
const showLess = button.find('.show-less');
setTimeout(() => {
if (showMore.length && showLess.length) {
if (showMore.is(':hidden')) {
showMore.show();
showLess.hide();
} else {
showMore.hide();
showLess.show();
}
}
}, 100);
});
}
// Document ready
$(document).ready(function() {
initializeFilters();
// Debug logging
console.log('Search filters initialized');
});
// Reinitialize after PJAX updates
$(document).on('pjax:complete', function() {
initializeFilters();
console.log('Filters reinitialized after PJAX');
});
// Handle PJAX errors
$(document).on('pjax:error', function(xhr, textStatus, error, options) {
console.log('PJAX Error:', error);
// Fallback to normal page load on error
window.location.href = options.url;
});
// Additional debugging for button clicks
$(document).on('click', 'button', function(e) {
console.log('Button clicked:', $(this).attr('id') || $(this).attr('class'), 'Event:', e);
});
// Prevent browser back/forward from causing issues
$(document).on('pjax:popstate', function() {
// Reinitialize filters when user uses browser navigation
setTimeout(initializeFilters, 100);
});
// Filter change handler
let filterTimeout = null;
function handleFilterChange() {
if (filterTimeout) {
clearTimeout(filterTimeout);
}
filterTimeout = setTimeout(function() {
const currentUrl = new URL(window.location.href);
const searchQuery = currentUrl.searchParams.get('q') || '';
currentUrl.search = '';
if (searchQuery) {
currentUrl.searchParams.set('q', searchQuery);
}
document.querySelectorAll('.filter-checkbox:checked, .filter-radio:checked').forEach(input => {
if (input.value !== '') {
if (input.name === 'features[]') {
currentUrl.searchParams.append('features[]', input.value);
} else {
currentUrl.searchParams.set(input.name, input.value);
}
}
});
$.pjax({
container: '#search-results',
url: currentUrl.toString(),
push: false,
replace: false,
timeout: 10000
});
}, 300);
}
// Event listeners
document.addEventListener('DOMContentLoaded', function () {
// Filter change listeners
document.addEventListener('change', function(e) {
if (e.target.matches('.filter-checkbox, .filter-radio')) {
handleFilterChange();
}
});
// Clear all filters buttons
document.addEventListener('click', function(e) {
if (e.target.matches('#clearAllFilters, .clear-all-filters')) {
clearAllFilters();
}
// Remove individual filter
if (e.target.matches('.remove-filter')) {
const filterType = e.target.getAttribute('data-filter');
const filterValue = e.target.getAttribute('data-value');
removeFilter(filterType, filterValue);
}
});
// Show more/less functionality
document.addEventListener('click', function(e) {
if (e.target.closest('[data-bs-toggle="collapse"]')) {
const button = e.target.closest('[data-bs-toggle="collapse"]');
const showMore = button.querySelector('.show-more');
const showLess = button.querySelector('.show-less');
setTimeout(() => {
if (showMore && showLess) {
if (showMore.style.display === 'none') {
showMore.style.display = 'inline';
showLess.style.display = 'none';
} else {
showMore.style.display = 'none';
showLess.style.display = 'inline';
}
}
}, 100);
}
});
// Auto-close offcanvas on filter change (optional)
document.addEventListener('change', function(e) {
if (e.target.matches('.filter-checkbox, .filter-radio')) {
// Optionally close after a short delay
// setTimeout(() => {
// const offcanvas = bootstrap.Offcanvas.getInstance(document.getElementById('filtersOffcanvas'));
// if (offcanvas) offcanvas.hide();
// }, 1000);
}
});
});
class GradSearch {
constructor() {
this.searchInput = null;
this.searchSuggestions = null;
this.searchForm = null;
this.debounceTimer = null;
this.selectedIndex = -1;
this.suggestions = [];
this.isLoading = false;
setTimeout(() => {
this.init();
}, 100);
}
init() {
this.searchInput = document.getElementById('search-input');
this.searchSuggestions = document.getElementById('search-suggestions');
this.searchForm = document.getElementById('main-search-form');
if (!this.searchInput || !this.searchSuggestions || !this.searchForm) {
console.error('Search elements not found');
return;
}
console.log('GradSearch initialized');
this.bindEvents();
}
bindEvents() {
this.searchInput.addEventListener('input', (e) => {
this.handleInput(e.target.value);
});
this.searchInput.addEventListener('focus', () => {
const value = this.searchInput.value.trim();
if (value.length === 0) {
this.loadPopularTerms();
} else {
this.loadSuggestions(value);
}
});
document.addEventListener('click', (e) => {
if (!this.searchInput.closest('.search-container').contains(e.target)) {
this.hideSuggestions();
}
});
this.searchInput.addEventListener('keydown', (e) => {
this.handleKeydown(e);
});
this.searchForm.addEventListener('submit', (e) => {
if (this.selectedIndex >= 0) {
e.preventDefault();
this.selectSuggestion(this.selectedIndex);
}
});
}
handleInput(value) {
clearTimeout(this.debounceTimer);
this.selectedIndex = -1;
if (value.trim().length === 0) {
this.loadPopularTerms();
return;
}
this.debounceTimer = setTimeout(() => {
this.loadSuggestions(value);
}, 200); // Faster response for better UX
}
async loadSuggestions(query) {
if (this.isLoading) return;
this.isLoading = true;
this.showLoadingState();
try {
const response = await fetch('/search/suggestions?q=' + encodeURIComponent(query));
if (!response.ok) throw new Error('Network response was not ok');
const data = await response.json();
this.renderSuggestions(data, query);
this.showSuggestions();
} catch (error) {
console.error('Search error:', error);
this.showErrorState();
} finally {
this.isLoading = false;
}
}
async loadPopularTerms() {
try {
const response = await fetch('/search/suggestions');
if (!response.ok) throw new Error('Network response was not ok');
const data = await response.json();
this.renderSuggestions(data, '');
this.showSuggestions();
} catch (error) {
console.error('Error loading popular terms:', error);
this.showErrorState();
}
}
showLoadingState() {
this.searchSuggestions.innerHTML = '';
} else {
html += '