PageSourceSearch

https://tecnofor.es/wp-content/plugins/SNGULAR-PLUGIN/assets/js/buscador-form.js?ver=1783416319

js tecnofor.es collected 2026-09-24 09:33:44 UTC 3,223 bytes, 82 lines download raw bytes

1document.addEventListener('DOMContentLoaded', function() {
2    const app = document.getElementById('buscador-form-app');
3    if (!app) return;
4
5    const searchInput = app.querySelector('#calendario-q');
6    const autocompleteContainer = app.querySelector('#autocomplete-results');
7    const keywords = calendario_ajax.keywords || [];
8    let currentArgs = calendario_ajax.initial_args || {};
9
10    function escapeRegExp(str) {
11        return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
12    }
13
14    function shouldShowAutocomplete(rawValue) {
15        const value = (rawValue || '').toLowerCase();
16        // Requisito: no autocompletar hasta tener 3 caracteres, y que exista un espacio
17        // (evita casos extremos tipo "IA" → coincidencias por contains).
18        if (value.length < 3) return false;
19        if (!value.includes(' ')) return false;
20        return true;
21    }
22
23    function keywordMatchesQuery(keyword, query) {
24        const q = (query || '').toLowerCase().trim();
25        if (!q) return false;
26        const terms = q.split(/\s+/).filter(Boolean);
27        const kw = (keyword || '').toLowerCase();
28
29        return terms.every(term => {
30            // Para términos muy cortos (p.ej. "IA") forzamos coincidencia por palabra completa.
31            if (term.length <= 2) {
32                const re = new RegExp(`(^|\\W)${escapeRegExp(term)}(\\W|$)`, 'i');
33                return re.test(keyword);
34            }
35            return kw.includes(term);
36        });
37    }
38
39    searchInput.addEventListener('input', function() {
40        const value = this.value.toLowerCase();
41        autocompleteContainer.innerHTML = '';
42        if (!value || !shouldShowAutocomplete(value)) {
43            autocompleteContainer.classList.remove('active');
44            return;
45        }
46
47        const suggestions = keywords.filter(kw => keywordMatchesQuery(kw, value)).slice(0, 7);
48
49        if (suggestions.length > 0) {
50            suggestions.forEach(suggestion => {
51                const item = document.createElement('div');
52                item.className = 'autocomplete-item';
53                // Resaltar la coincidencia
54                const safe = escapeRegExp(value.trim());
55                const regex = safe ? new RegExp(`(${safe})`, 'gi') : null;
56                item.innerHTML = regex ? suggestion.replace(regex, '<strong>$1</strong>') : suggestion;
57
58                item.addEventListener('click', function() {
59                    searchInput.value = suggestion;
60                    autocompleteContainer.classList.remove('active');
61                    currentArgs.paged = 1;
62                    const form = searchInput.closest('form');
63                    if (form) {
64                        form.submit();
65                    }
66                });
67                autocompleteContainer.appendChild(item);
68            });
69            autocompleteContainer.classList.add('active');
70        } else {
71            autocompleteContainer.classList.remove('active');
72        }
73    });
74
75    // Cerrar el autocompletado si se hace clic fuera
76    document.addEventListener('click', function(e) {
77        if (e.target !== searchInput) {
78            autocompleteContainer.classList.remove('active');
79        }
80    });
81
82});

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.