1(function($) { 2 'use strict'; 3 4 /** 5 * Reviews Filtering and Pagination via AJAX 6 */ 7 let ReviewsFilters = { 8 container: null, 9 filtersForm: null, 10 loading: false, 11 productId: null, 12 13 init: function() { 14 this.container = $('.s-reviews_wrap'); 15 this.filtersForm = $('.s-reviews_filters'); 16 17 if (!this.container.length || !this.filtersForm.length) { 18 return; 19 } 20 21 // Check if this is a product-specific review section 22 let $reviewSection = this.filtersForm.closest('.s-reviews'); 23 this.productId = $reviewSection.data('product-id'); 24 25 console.log('MMPR Filters initialized. Product ID:', this.productId); 26 27 this.bindEvents(); 28 }, 29 30 bindEvents: function() { 31 let self = this; 32 33 // Filter change events 34 this.filtersForm.on('change', 'select', function(e) { 35 e.preventDefault(); 36 console.log('MMPR: Filter changed:', $(this).attr('name'), '=', $(this).val()); 37 self.loadReviews(1); // Reset to page 1 on filter change 38 }); 39 40 // Handle custom styled selects (clicks on custom-select__option) 41 // This is for theme's custom select styling 42 $(document).on('click', '.custom-select__option', function() { 43 // Small delay to let the custom select update the real select value 44 setTimeout(function() { 45 console.log('MMPR: Custom select option clicked, triggering filter load'); 46 self.loadReviews(1); 47 }, 50); 48 }); 49 50 // Pagination click events (delegated) 51 $(document).on('click', '.s-reviews-page-numbers', function(e) { 52 e.preventDefault(); 53 54 if ($(this).hasClass('current') || $(this).hasClass('s-reviews-no-page')) { 55 return; 56 } 57 58 let page = $(this).data('page'); 59 if (page) { 60 console.log('MMPR: Pagination clicked. Page:', page); 61 self.loadReviews(page); 62 } 63 }); 64 }, 65 66 loadReviews: function(page) { 67 if (this.loading) { 68 console.log('MMPR: Already loading, skipping...'); 69 return; 70 } 71 72 this.loading = true; 73 this.container.addClass('loading'); 74 75 // Add preload class to content area 76 this.container.find('.s-reviews_content').addClass('preload'); 77 78 let self = this; 79 let orderBy = this.filtersForm.find('select[name="order_by"]').val() || 'newest'; 80 let rating = this.filtersForm.find('select[name="rating"]').val() || ''; 81 82 // Determine which AJAX action to use 83 let ajaxAction = this.productId ? 'mmpr_load_product_reviews' : 'mmpr_load_reviews'; 84 85 let ajaxData = { 86 action: ajaxAction, 87 nonce: memoPhotoReviews.nonce, 88 page: page, 89 order_by: orderBy, 90 rating: rating 91 }; 92 93 // Add product_id if this is product-specific 94 if (this.productId) { 95 ajaxData.product_id = this.productId; 96 } 97 98 console.log('MMPR: Loading reviews with data:', ajaxData); 99 100 $.ajax({ 101 url: memoPhotoReviews.ajaxUrl, 102 type: 'POST', 103 data: ajaxData, 104 success: function(response) { 105 console.log('MMPR: Response received', response); 106 107 if (response.success && response.data) { 108 console.log('MMPR: Total pages:', response.data.total_pages); 109 console.log('MMPR: Current page:', response.data.current_page); 110 console.log('MMPR: Total reviews:', response.data.total); 111 console.log('MMPR: Filters:', response.data.filters); 112 113 // Update reviews list 114 if (response.data.reviews) { 115 self.container.find('.s-reviews_content').html(response.data.reviews); 116 console.log('MMPR: Reviews HTML updated'); 117 } 118 119 // Update pagination 120 if (response.data.pagination) { 121 console.log('MMPR: Pagination HTML:', response.data.pagination); 122 $('.s-reviews-pagination').html(response.data.pagination); 123 console.log('MMPR: Pagination HTML updated'); 124 } else if (response.data.total_pages <= 1) { 125 // Hide pagination if only one page 126 $('.s-reviews-pagination').html(''); 127 console.log('MMPR: Pagination hidden (single page)'); 128 } // Scroll to reviews 129 if ($('.s-reviews').length) { 130 $('html, body').animate({ 131 scrollTop: $('.s-reviews').offset().top - 100 132 }, 300); 133 } 134 } else { 135 console.error('MMPR: Error loading reviews', response); 136 137 // Display error message to user 138 if (response.data && response.data.message) { 139 self.container.find('.s-reviews_content').html( 140 '<div class="mmpr-error-message">' + response.data.message + '</div>' 141 ); 142 } 143 } 144 }, 145 error: function(xhr, status, error) { 146 console.error('MMPR: AJAX error', error, xhr.responseText); 147 148 // Display generic error message 149 self.container.find('.s-reviews_content').html( 150 '<div class="mmpr-error-message">
150An error occurred while loading reviews. Please try again.</div>' 151 ); 152 }, 153 complete: function() { 154 self.loading = false; 155 self.container.removeClass('loading'); 156 157 // Remove preload class from content area 158 self.container.find('.s-reviews_content').removeClass('preload'); 159 } 160 }); 161 } 162 }; 163 164 // Initialize on document ready 165 $(document).ready(function() { 166 ReviewsFilters.init(); 167 }); 168 169})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.