PageSourceSearch

https://acninternational.org/wp-content/themes/acn-international/js/acn-ajax-filter-url.js?ver=1.0.1

js acninternational.org collected 2026-10-02 03:33:56 UTC 4,058 bytes, 119 lines download raw bytes

1(function () {
2  // Simple flag to confirm script is loaded
3  window.__ACN_URL_SYNC_LOADED = true;
4
5  function $all(p, s) { return Array.from(p.querySelectorAll(s)); }
6
7  function readChecked(form) {
8    const map = {}; // {category:[slug,...], country:[slug,...]}
9    $all(form, 'input[type="checkbox"]:checked').forEach(cb => {
10      const m = cb.name.match(/^([a-z_]+)\[\]$/i);
11      if (!m) return;
12      const key  = m[1].toLowerCase();
13      const slug = (cb.dataset.slug || cb.value || '').toString().trim();
14      if (!slug) return;
15      const arr = (map[key] ||= []);
16      if (!arr.includes(slug)) arr.push(slug);
17    });
18    return map;
19  }
20
21  function writeURL(paramMap) {
22    const params = new URLSearchParams(location.search);
23    ['category','country','continent'].forEach(k => params.delete(k));
24    Object.keys(paramMap).sort().forEach(k => {
25      if (paramMap[k].length) params.set(k, paramMap[k].join(','));
26    });
27    const qs = params.toString();
28    const newUrl = qs ? `${location.pathname}?${qs}` : location.pathname;
29    history.pushState({}, '', newUrl);
30    return qs;
31  }
32
33  function hydrateFromURL(form) {
34    const params = new URLSearchParams(location.search);
35    // Clear previous selections to reflect URL exactly
36    $all(form, 'input[type="checkbox"]').forEach(cb => { cb.checked = false; });
37    ['category','country','continent'].forEach(k => {
38      const val = params.get(k);
39      if (!val) return;
40      val.split(',').forEach(slug => {
41        const el =
42          form.querySelector(`input[name="${k}[]"][data-slug="${slug}"]`) ||
43          form.querySelector(`input[name="${k}[]"][value="${slug}"]`);
44        if (el) el.checked = true;
45      });
46    });
47    filterCountriesByContinents(form);
48  }
49
50  function getSelectedContinentSlugs(form){
51    const arr = [];
52    $all(form, 'input[name="continent[]"]:checked').forEach(cb => {
53      const slug = (cb.dataset.slug || '').trim();
54      if (slug && !arr.includes(slug)) arr.push(slug);
55    });
56    return arr;
57  }
58
59  function filterCountriesByContinents(form){
60    const selectedConts = getSelectedContinentSlugs(form);
61    const items = $all(form, 'li.form-check input[name="country[]"]').map(inp => inp.closest('li.form-check'));
62    if (!selectedConts.length){
63      items.forEach(li => { li.style.display = ''; });
64      return;
65    }
66    items.forEach(li => {
67      const conts = (li.getAttribute('data-continents') || '').split(',').filter(Boolean);
68      const match = conts.some(c => selectedConts.includes(c));
69      li.style.display = match ? '' : 'none';
70      // If hidden, also uncheck
71      if (!match){
72        const cb = li.querySelector('input[type="checkbox"]');
73        if (cb) cb.checked = false;
74      }
75    });
76  }
77
78  function onSubmit(e) {
79    const form = e.target.closest('.cpt-filter-form');
80    if (!form) return;
81    e.preventDefault();
82    // Keep UI filtered based on continents before reading checked values
83    filterCountriesByContinents(form);
84    const map = readChecked(form);
85    const qs  = writeURL(map);
86
87    // ping your loader
88    const cptId = form.dataset.cptId;
89    if (cptId) {
90      window.dispatchEvent(new CustomEvent('acn:filter-change', {
91        detail: { cptId, params: qs }
92      }));
93    }
94  }
95
96  document.addEventListener('submit', onSubmit);
97
98  // First load + back/forward support
99  function init() {
100    document.querySelectorAll('.cpt-filter-form').forEach(form => {
101      hydrateFromURL(form);
102      // Live filtering when continents change
103      form.addEventListener('change', (ev) => {
104        const t = ev.target;
105        if (!t || !t.name) return;
106        if (t.name === 'continent[]'){
107          filterCountriesByContinents(form);
108        }
109      });
110    });
111  }
112  document.addEventListener('DOMContentLoaded', init);
113  window.addEventListener('popstate', () => {
114    // Re-run your filter when user clicks Back/Forward
115    document.querySelectorAll('.cpt-filter-form').forEach(form => {
116      form.dispatchEvent(new Event('submit', { cancelable: true, bubbles: true }));
117    });
118  });
119})();

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.