PageSourceSearch

https://www.marq.com/wp-content/themes/marq/js/ajax.js?ver=1790238983

js marq.com collected 2026-09-24 08:37:31 UTC 6,176 bytes, 168 lines download raw bytes

1(function () {
2    'use strict';
3
4    if (typeof marqAjax === 'undefined') return;
5
6    var sections = document.querySelectorAll('.case-studies-section');
7    if (!sections.length) return;
8
9    sections.forEach(initSection);
10
11    function initSection(section) {
12        var action       = section.dataset.ajaxAction || 'marq_filter_posts';
13        var perPage      = parseInt(section.dataset.perPage, 10) || 6;
14        var allowedCats  = (section.dataset.allowedCats || '')
15            .split(',').map(function (n) { return parseInt(n, 10); }).filter(Boolean);
16        var byCategory   = section.dataset.byCategory === '1';
17
18        var grid         = section.querySelector('.posts-grid, .case-studies-grid');
19        var noPostsMsg   = section.querySelector('.no-posts-message');
20        var loadMoreRow  = section.querySelector('.load-more-row');
21        var loadMoreBtn  = section.querySelector('.load-more-posts, .load-more-case-studies');
22        var filterBtns   = section.querySelectorAll('.filter-btn');
23        var searchForm   = section.querySelector('.search-form');
24        var searchInput  = section.querySelector('.search-input');
25        var searchClear  = section.querySelector('.search-clear');
26
27        if (!grid) return;
28
29        var state = {
30            category: 'all',
31            search:   '',
32            page:     1,
33            loading:  false
34        };
35
36        // Filter button clicks
37        filterBtns.forEach(function (btn) {
38            btn.addEventListener('click', function () {
39                if (state.loading) return;
40                var cat = btn.dataset.category;
41                setActiveFilter(btn);
42                if (searchInput) searchInput.value = '';
43                toggleClearBtn(false);
44                state.category = cat;
45                state.search   = '';
46                state.page     = 1;
47                fetchPosts({ append: false });
48            });
49        });
50
51        // Search submit (Enter or magnifying glass click)
52        if (searchForm) {
53            searchForm.addEventListener('submit', function (e) {
54                e.preventDefault();
55                if (state.loading) return;
56                state.search = searchInput ? searchInput.value.trim() : '';
57                state.page   = 1;
58                toggleClearBtn(state.search !== '');
59                fetchPosts({ append: false });
60            });
61        }
62
63        // Clear search (X button)
64        if (searchClear) {
65            searchClear.addEventListener('click', function () {
66                if (state.loading) return;
67                if (searchInput) searchInput.value = '';
68                state.search = '';
69                state.page   = 1;
70                toggleClearBtn(false);
71                fetchPosts({ append: false });
72            });
73        }
74
75        // Load more
76        if (loadMoreBtn) {
77            loadMoreBtn.addEventListener('click', function () {
78                if (state.loading) return;
79                state.page = parseInt(loadMoreBtn.dataset.page, 10) + 1;
80                fetchPosts({ append: true });
81            });
82        }
83
84        function toggleClearBtn(show) {
85            if (!searchClear) return;
86            if (show) {
87                searchClear.removeAttribute('hidden');
88            } else {
89                searchClear.setAttribute('hidden', '');
90            }
91        }
92
93        function setActiveFilter(activeBtn) {
94            filterBtns.forEach(function (b) {
95                b.classList.remove('active');
96                if (!b.classList.contains('black_outline')) {
97                    b.classList.add('black_outline');
98                }
99            });
100            activeBtn.classList.add('active');
101            activeBtn.classList.remove('black_outline');
102        }
103
104        function fetchPosts(opts) {
105            state.loading = true;
106            grid.classList.add('is-loading');
107
108            var formData = new FormData();
109            formData.append('action',       action);
110            formData.append('nonce',        marqAjax.nonce);
111            formData.append('category',     state.category);
112            formData.append('search',       state.search);
113            formData.append('page',         state.page);
114            formData.append('per_page',     perPage);
115            formData.append('by_category',  byCategory ? '1' : '0');
116            formData.append('allowed_cats', allowedCats.join(','));
117
118            fetch(marqAjax.ajax_url, {
119                method: 'POST',
120                credentials: 'same-origin',
121                body: formData
122            })
123            .then(function (r) { return r.json(); })
124            .then(function (res) {
125                if (!res || !res.success) {
126                    throw new Error('AJAX error');
127                }
128                renderResponse(res.data, opts.append);
129            })
130            .catch(function (err) {
131                console.error('marq AJAX:', err);
132            })
133            .finally(function () {
134                state.loading = false;
135                grid.classList.remove('is-loading');
136            });
137        }
138
139        function renderResponse(data, append) {
140            var html      = data.html || '';
141            var hasMore   = !!data.has_more;
142            var found     = parseInt(data.found, 10) || 0;
143            var maxPages  = parseInt(data.max_pages, 10) || 1;
144
145            if (append) {
146                grid.insertAdjacentHTML('beforeend', html);
147            } else {
148                grid.innerHTML = html;
149            }
150
151            // Toggle grid visibility + no-posts message
152            if (found === 0 && !append) {
153                grid.style.display = 'none';
154                if (noPostsMsg) noPostsMsg.style.display = '';
155            } else {
156                grid.style.display = '';
157                if (noPostsMsg) noPostsMsg.style.display = 'none';
158            }
159
160            // Load More button state
161            if (loadMoreBtn && loadMoreRow) {
162                loadMoreBtn.dataset.page      = state.page;
163                loadMoreBtn.dataset.maxPages  = maxPages;
164                loadMoreRow.style.display     = hasMore ? '' : 'none';
165            }
166        }
167    }
168})();

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.