Bible Search

(function($) { 'use strict'; // Variables let currentPage = 1; let isSearching = false; let lastSearchParams = {}; // Initialize once DOM is fully loaded $(document).ready(function() { initializeSearch(); }); /** * Initialize the search functionality */ function initializeSearch() { const $form = $('#bible-advanced-search-form'); const $results = $('#search-results'); const $status = $('#search-status'); // Handle form submission $form.on('submit', function(e) { e.preventDefault(); // Reset to first page on new search currentPage = 1; // Get form data const searchParams = { term: $('#search-term').val(), book: $('#bible-book').val(), post_type: $('#content-type').val(), topic: $('#bible-topic').val() }; // Store for pagination lastSearchParams = searchParams; // Execute search performSearch(searchParams); }); // Handle "Load More" clicks when it exists $results.on('click', '.load-more-button', function() { currentPage++; const loadMoreParams = Object.assign({}, lastSearchParams, { page: currentPage }); performSearch(loadMoreParams, true); }); } /** * Perform the search via AJAX */ function performSearch(params, append = false) { const $results = $('#search-results'); const $status = $('#search-status'); // Prevent multiple simultaneous searches if (isSearching) return; // Update UI to show loading isSearching = true; $status.text(bibleSearchData.loading_text).addClass('loading').removeClass('error no-results'); if (!append) { $results.empty(); } // Make AJAX request to our REST API endpoint $.ajax({ url: bibleSearchData.api_url, method: 'GET', data: params, beforeSend: function(xhr) { xhr.setRequestHeader('X-WP-Nonce', bibleSearchData.nonce); }, success: function(response) { // Clear loading status $status.removeClass('loading'); if (response.success && response.count > 0) { // Results found $status.empty().removeClass('no-results'); // If this is a new search (not appending), render the header if (!append) { renderSearchHeader(response); } // Render results renderSearchResults(response.results, append); } else { // No results if (!append) { $results.empty(); $status.text(bibleSearchData.no_results_text).addClass('no-results'); } else { // Remove "Load More" button if no additional results $results.find('.load-more-container').remove(); } } }, error: function() { $status.text(bibleSearchData.error_text).removeClass('loading').addClass('error'); }, complete: function() { isSearching = false; } }); } /** * Render the search header with result count and type breakdown */ function renderSearchHeader(response) { const $results = $('#search-results'); let header = `
Found ${response.count} results
`; // Add result type badges if multiple types found if (Object.keys(response.post_types_found).length > 1) { header += '
'; for (const [postType, count] of Object.entries(response.post_types_found)) { const label = formatPostTypeLabel(postType); header += `
${label} ${count}
`; } header += '
'; } $results.append(header); } /** * Render the search results */ function renderSearchResults(results, append) { const $results = $('#search-results'); // Remove existing "Load More" button if appending if (append) { $results.find('.load-more-container').remove(); } // Render each result item results.forEach(function(item) { const resultHtml = `

${highlightSearchTerm(item.title)}

${item.post_type_label}
${item.date}
${highlightSearchTerm(item.excerpt)}
${renderBooksList(item.books)} ${renderTopicsList(item.topics)}
`; $results.append(resultHtml); }); // Add "Load More" button if we have enough results if (results.length >= 10) { $results.append(`
`); } // Scroll to results if this is a new search if (!append) { $('html, body').animate({ scrollTop: $results.offset().top - 100 }, 500); } } /** * Render books list for a result item */ function renderBooksList(books) { if (!books || books.length === 0) { return ''; } let html = '
'; html += 'Books: '; books.forEach(function(book) { html += `${book}`; }); html += '
'; return html; } /** * Render topics list for a result item */ function renderTopicsList(topics) { if (!topics || topics.length === 0) { return ''; } let html = '
'; html += 'Topics: '; topics.forEach(function(topic) { html += `${topic}`; }); html += '
'; return html; } /** * Highlight search term in text */ function highlightSearchTerm(text) { const searchTerm = $('#search-term').val().trim(); if (!searchTerm || !text) { return text; } // Split search term into words for better matching const terms = searchTerm.split(' ').filter(term => term.length > 2); if (terms.length === 0) { return text; } // Create a regex to match all search terms const pattern = new RegExp('(' + terms.join('|') + ')', 'gi'); return text.replace(pattern, '$1'); } /** * Format post type into readable label */ function formatPostTypeLabel(postType) { const labels = { 'reading_hub': 'Daily Readings', 'commentary': 'Commentary', 'devotionals': 'Devotionals', 'proverb_nuggets': 'Proverb Nuggets', 'topic_studies': 'Topic Studies', 'memory_verses': 'Memory Verses' }; return labels[postType] || postType.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase()); } })(jQuery);