PageSourceSearch

https://churchofpug.com/wp-content/themes/buzz-rescues-child/assets/js/buzz-master.js

js churchofpug.com collected 2026-10-07 01:24:31 UTC 15,184 bytes, 516 lines download raw bytes

1// JavaScript Document
2// Author Name: Dezinethemes
3// Author URI: http://www.dezinethemes.com
4// Creation Date: 8 Aug 2018
5
6// Utility functions
7function debounce(func, wait) {
8	var timeout;
9	return function() {
10		var context = this;
11		var args = arguments;
12		clearTimeout(timeout);
13		timeout = setTimeout(function() {
14			func.apply(context, args);
15		}, wait);
16	};
17}
18
19function autoTabDates($) {
20    $(".ginput_container_date > input").keyup(function () {
21        if (this.value.length == this.maxLength) {
22          $(this).closest('.ginput_container_date').next('.ginput_container_date').find('input').focus();
23        }
24    });
25}
26
27// load DOM
28(function($) {
29    'use strict';
30
31    // Cache DOM elements
32    var $window = $(window);
33    var $body = $('body');
34    var $header = $('.Bzl-header');
35    var $dogsContainer = $('.buzz-dogs-shortcode');
36    var $catsContainer = $('.buzz-cats-shortcode');
37    var $advancedSearch = $('#buzz_advanced_search');
38    
39    $window.on("load", function() {
40        $('#wpadminbar a.screen-reader-shortcut').removeAttr('tabindex');
41        if($(".ginput_container_date").length > 0) {
42            autoTabDates($);
43        }
44        $(document).on('gform_page_loaded', function(event, form_id, current_page) {
45            if($(".ginput_container_date").length > 0) {
46                autoTabDates($);
47            }
48        });
49    });
50	
51    // Navigation Menu Slider - оптимизированная версия
52    $('#nav-expander, #nav-expander-m').on('click', function() {
53        $body.toggleClass('nav-expanded');
54    });
55    
56    $('#nav-close, #nav-close-m').on('click', function() {
57        $body.removeClass('nav-expanded');
58    });
59    
60    // Top Arrow - оптимизированная версия с requestAnimationFrame
61    var ticking = false;
62    $window.scroll(function() {
63        if (!ticking) {
64            window.requestAnimationFrame(function() {
65                if ($window.scrollTop() > 1000) {
66                    $('a.top').fadeIn(150);
67                } else {
68                    $('a.top').fadeOut(150);
69                }
70                ticking = false;
71            });
72            ticking = true;
73        }
74    });
75    
76    // Fixed Top bar - оптимизированная версия
77    var lastScrollTop = 0;
78    $window.scroll(debounce(function() {
79        var scrollTop = $window.scrollTop();
80        if (scrollTop > 5) {
81            $header.addClass('sticky');
82        } else {
83            $header.removeClass('sticky');
84        }
85        lastScrollTop = scrollTop;
86    }, 10));
87    
88    // Donation Dropdown - оптимизированная версия
89    $('#dog_sponsor, #cat_sponsor').on("click", function(e) {
90		e.preventDefault();
91        var $target = $(this).attr('id') === 'dog_sponsor' ? $('#dog_sponsor_box') : $('#cat_sponsor_box');
92        $target.slideToggle(150);
93	});
94	
95    // Tooltips - оптимизированная версия
96    $('[data-toggle="tooltip"]').addClass('ttip').tooltip();
97	
98    // Advanced Filter - оптимизированная версия
99    $('.buzz-dogs-shortcode a.Bzl-afl, .buzz-cats-shortcode a.Bzl-afl').on("click", function(e) {
100		e.preventDefault();
101        $advancedSearch.toggleClass('d-none');
102    });
103    
104    // Simple JS Filter for OLD shortcode (without AJAX) - just hide/show
105    var bz_simpleFilter = {
106        init: function() {
107            // Only for OLD shortcode (without .Bzl-ajax-mode)
108            if ($('.Bzl-dogs-listing').length && !$('.Bzl-dogs-listing.Bzl-ajax-mode').length) {
109                this.bindEvents();
110            }
111            return this;
112        },
113        
114        bindEvents: function() {
115            var self = this;
116            $('#buzz_advanced_search .ads_search').on('change keyup', debounce(function() {
117                self.filterDogs();
118            }, 300));
119            
120            $('#ads_clear_filter').on('click', function() {
121                $('#buzz_advanced_search .ads_search').val('');
122                self.filterDogs();
123            });
124        },
125        
126        filterDogs: function() {
127            var filters = {};
128            $('#buzz_advanced_search .ads_search').each(function() {
129                var name = $(this).data('attribute-name');
130                var value = $(this).val();
131                if (value) {
132                    filters[name] = value.toLowerCase();
133                }
134            });
135            
136            $('.Bzl-dogs-listing .type-dog').each(function() {
137                var $dog = $(this);
138                var show = true;
139                
140                for (var attr in filters) {
141                    var dogValue = $dog.data(attr);
142                    if (dogValue) {
143                        dogValue = String(dogValue).toLowerCase();
144                        // For text search (name, breed)
145                        if (attr === 'name' || attr === 'breed') {
146                            if (dogValue.indexOf(filters[attr]) === -1) {
147                                show = false;
148                                break;
149                            }
150                        } else {
151                            // For exact match (gender, color, etc)
152                            if (dogValue !== filters[attr]) {
153                                show = false;
154                                break;
155                            }
156                        }
157                    } else {
158                        show = false;
159                        break;
160                    }
161                }
162                
163                if (show) {
164                    $dog.show();
165                } else {
166                    $dog.hide();
167                }
168            });
169        }
170    };
171    
172    // Advanced Search Filter FOR DOGS - AJAX + Infinite Scroll (NEW shortcode only)
173	var bz_searchManager = {
174		page: 1,
175		loading: false,
176		hasMore: true,
177		filters: {},
178		currentRequest: null,
179		requestToken: 0,
180		
181		init: function() {
182			// Only for NEW shortcode with .Bzl-ajax-mode
183			if (!$('.Bzl-dogs-listing.Bzl-ajax-mode').length) {
184				return this;
185			}
186			
187			// Check if AJAX is available
188			if (typeof dogFilterAjax === 'undefined') {
189				console.error('dogFilterAjax is not defined! AJAX will not work.');
190				return this;
191			}
192			
193			this.bindEvents();
194			this.loadInitialDogs();
195			return this;
196		},
197		
198		bindEvents: function() {
199			var self = this;
200			
201			// Text inputs wait for typing to stop before searching.
202			$('#buzz_advanced_search input.ads_search').on('input', debounce(function() {
203				self.filters = self.getFilters();
204				self.resetAndLoad();
205			}, 1000));
206
207			// Selects can refresh immediately on change.
208			$('#buzz_advanced_search select.ads_search').on('change', function() {
209				self.filters = self.getFilters();
210				self.resetAndLoad();
211			});
212			
213			// Clear filters button
214			$('#ads_clear_filter').on('click', function() {
215				// Clear all filter inputs
216				$('#buzz_advanced_search .ads_search').val('');
217				// Reset filters and reload
218				self.filters = {};
219				self.resetAndLoad();
220			});
221			
222			// Scroll detection
223			$(window).on('scroll', debounce(function() {
224				self.checkScroll();
225			}, 100));
226		},
227		
228		getFilters: function() {
229			var filters = {};
230			$('#buzz_advanced_search .ads_search').each(function() {
231				var name = $(this).data('attribute-name');
232				var value = $(this).val();
233				if (value) {
234					filters[name] = value;
235				}
236			});
237			return filters;
238		},
239		
240		loadInitialDogs: function() {
241			// Only load if we're on a page with AJAX dog listing (not pagination version)
242			if ($('.Bzl-dogs-listing.Bzl-ajax-mode').length && $('.type-dog').length === 0) {
243				this.loadMore();
244			}
245		},
246		
247		resetAndLoad: function() {
248			this.abortCurrentRequest();
249			this.page = 1;
250			this.hasMore = true;
251			this.loading = false;
252			$('.Bzl-dogs-listing.Bzl-ajax-mode .type-dog').remove();
253			$('#dogs-loader, #dogs-end').remove();
254			// Remove "No dogs found" message too
255			$('.Bzl-dogs-listing.Bzl-ajax-mode .col-12.text-center').remove();
256			this.loadMore();
257		},
258		
259		checkScroll: function() {
260			if (this.loading || !this.hasMore) return;
261			// Only work with AJAX mode, not pagination mode
262			if ($('.Bzl-dogs-listing.Bzl-ajax-mode').length === 0) return;
263			
264			var scrollTop = $(window).scrollTop();
265			var windowHeight = $(window).height();
266			var docHeight = $(document).height();
267			
268			// Trigger at 70% for mobile-friendly loading
269			if (scrollTop + windowHeight >= docHeight * 0.7) {
270				this.loadMore();
271			}
272		},
273		
274		loadMore: function() {
275			var self = this;
276			var requestToken;
277			
278			if (self.loading) return;
279			self.loading = true;
280			requestToken = ++self.requestToken;
281			
282			// Show loader
283			self.showLoader();
284			
285			self.currentRequest = $.ajax({
286				url: dogFilterAjax.ajax_url,
287				type: 'POST',
288				data: {
289					action: 'filter_dogs',
290					nonce: dogFilterAjax.nonce,
291					filters: self.filters,
292					page: self.page,
293					per_page: 8
294				},
295				success: function(response) {
296					if (requestToken !== self.requestToken) {
297						return;
298					}
299
300					self.currentRequest = null;
301					self.hideLoader();
302					
303					if (response.success && response.data.html && response.data.html.trim() !== '') {
304						// Append new dogs (only to AJAX mode container)
305						$('.Bzl-dogs-listing.Bzl-ajax-mode').append(response.data.html);
306						
307						// Update state
308						self.page++;
309						self.hasMore = self.page <= response.data.max_pages;
310						
311						// Show end message if no more dogs
312						if (!self.hasMore) {
313							self.showEndMessage(response.data.total);
314						}
315					} else {
316						// No dogs found - only show message if page 1 and found 0
317						if (self.page === 1 && response.data.found === 0) {
318							self.showNoResults();
319						}
320						self.hasMore = false;
321					}
322					
323					self.loading = false;
324				},
325				error: function(xhr, status, error) {
326					if (status === 'abort') {
327						return;
328					}
329
330					if (requestToken !== self.requestToken) {
331						return;
332					}
333
334					self.currentRequest = null;
335					console.error('AJAX Error:', xhr.responseText, status, error);
336					self.hideLoader();
337					self.showError();
338					self.loading = false;
339				}
340			});
341		},
342
343		abortCurrentRequest: function() {
344			if (this.currentRequest && this.currentRequest.readyState !== 4) {
345				this.currentRequest.abort();
346			}
347
348			this.currentRequest = null;
349		},
350		
351		showLoader: function() {
352			if (!$('#dogs-loader').length) {
353				$('.Bzl-dogs-listing.Bzl-ajax-mode').after(
354					'<div id="dogs-loader" class="text-center pT3 pB3">' +
355					'<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">' +
356					'<span class="sr-only">Loading...</span>' +
357					'</div>' +
358					'<p class="pT2">Loading more dogs...</p>' +
359					'</div>'
360				);
361			}
362		},
363		
364		hideLoader: function() {
365			$('#dogs-loader').remove();
366		},
367		
368		showEndMessage: function(total) {
369			if (!$('#dogs-end').length) {
370				$('.Bzl-dogs-listing.Bzl-ajax-mode').after(
371					'<div id="dogs-end" class="text-center pT3 pB3">' +
372					'<p style="font-size: 1.2rem;">🐾 All ' + total + ' dog' + (total !== 1 ? 's' : '') + ' loaded!</p>' +
373					'</div>'
374				);
375			}
376		},
377		
378		showNoResults: function() {
379			$('.Bzl-dogs-listing.Bzl-ajax-mode').html(
380				'<div class="col-12 text-center pT5 pB5">' +
381				'<h3>No dogs found</h3>' +
382				'<p>Try adjusting your filters to see more results.</p>' +
383				'</div>'
384			);
385		},
386		
387		showError: function() {
388			alert('Error loading dogs. Please refresh the page and try again.');
389		},
390		
391		run: function() {
392			// Legacy method for compatibility
393			return this;
394		}
395	};
396	
397	// Initialize both filters
398	bz_simpleFilter.init();  // Simple JS filter for old shortcode
399	bz_searchManager.init(); // AJAX filter for new shortcode
400    
401    // Advanced Search Filter FOR CATS - оптимизированная версия
402    var catSearchManager = {
403		_searchValues: [],
404        _cachedElements: null,
405        
406        init: function() {
407            this._cachedElements = $('.type-cat');
408            return this;
409        },
410        
411	run: function() {
412		var self = this;
413            $('#buzz_advanced_search').on('change keyup', '.ads_search', debounce(function() {
414                var attrName = $(this).attr('data-attribute-name');
415                var attrValue = $(this).val().toLowerCase();
416			self._searchValues[attrName] = attrValue;
417			self.sortTheCats();
418            }, 250));
419	},		sortTheCats: function() {
420		var self = this;
421            var $container = $('.Bzl-dogs-listing');
422            
423            // First, show all cached elements
424            $container.append(this._cachedElements);
425            
426            // Then hide the ones that don't match
427            this._cachedElements.each(function() {
428			var isValid = true;
429				for (var i in self._searchValues) {
430                    var attributeValue = self._searchValues[i];
431                    if (!attributeValue || attributeValue.length === 0) continue;
432                    
433                    var elementValue = $(this).attr('data-' + i)?.toLowerCase();
434                    if (i === "name") {
435						if (!elementValue || !elementValue.includes(attributeValue)) {
436							isValid = false;
437							break;
438						}
439					} else {
440						if (!elementValue || elementValue !== attributeValue) {
441							isValid = false;
442							break;
443						}
444					}
445				}
446	
447				if (isValid) {
448                    $(this).show();
449                } else {
450                    $(this).hide();
451                }
452            });
453        }
454    };
455    
456    catSearchManager.init().run();
457    
458    // Clear filters - оптимизированная версия
459	$(document).on('click', '#ads_clear_filter', function() {
460		$('#buzz_advanced_search select.ads_search').prop('selectedIndex', 0);
461        $('#buzz_advanced_search input.ads_search').val('');
462        
463        // Reset search values
464        bz_searchManager._searchValues = [];
465        catSearchManager._searchValues = [];
466        
467        // Show all elements
468        $('.type-dog, .type-cat').show();
469    });
470    
471    // Equal Heights - оптимизированная версия
472    function equalHeights() {
473        var maxHeight = 0;
474        $('.equal-height').each(function() {
475            var height = $(this).height();
476            maxHeight = height > maxHeight ? height : maxHeight;
477        }).height(maxHeight);
478    }
479    
480    // Call equalHeights on window resize with debounce
481    $window.resize(debounce(equalHeights, 250));
482    
483	// Initial call to equalHeights
484	equalHeights();
485
486	// Initialize Magnific Popup gallery/lightbox when the plugin is present
487	if ($.fn.magnificPopup) {
488		$('.Bzl-popup-gallery').magnificPopup({
489			delegate: 'a',
490			type: 'image',
491			gallery: {
492				enabled: true
493			},
494			callbacks: {
495				elementParse: function(item) {
496					if (item.el.hasClass('popupVideo')) {
497						item.type = 'iframe';
498					} else {
499						item.type = 'image';
500					}
501				}
502			}
503		});
504
505		$('.popupVideo').magnificPopup({
506			type: 'iframe',
507			mainClass: 'mfp-fade',
508			removalDelay: 160,
509			preloader: false,
510			fixedContentPos: false
511		});
512	} else {
513		console.warn('Magnific Popup is not available; gallery lightbox is disabled.');
514	}
515
516})(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.