1/** 2 * ÐÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ Ð¾Ð±ÐµÑпеÑÐ¸Ð²Ð°ÐµÑ ÑабоÑÑ "живого поиÑка" на ÑÑÑаниÑе 3 * ÐавиÑÐ¸Ñ Ð¾Ñ autoComplete.js 4 */ 5new class SearchLine extends RsJsCore.classes.component 6{ 7 onDocumentReady() 8 { 9 let searchLine = document.querySelector('.rs-search-line'); 10 11 let input = searchLine && searchLine.querySelector('.rs-autocomplete'); 12 let resultWrapper = searchLine && searchLine.querySelector('.rs-autocomplete-result'); 13 let clearButton = searchLine && searchLine.querySelector('.rs-autocomplete-clear'); 14 let cancelController; 15 16 if (input && input.dataset.sourceUrl) { 17 if (clearButton) { 18 input.addEventListener('keyup', (event) => { 19 clearButton.classList.toggle('d-none', event.target.value === ''); 20 }); 21 22 clearButton.addEventListener('click', (event) => { 23 input.value = ''; 24 input.dispatchEvent(new Event('keyup')); 25 input.dispatchEvent(new Event('keydown')); 26 }); 27 } 28 29 let onEnter = (event) => { 30 if (event.key === 'Enter') { 31 event.target.closest('form').submit(); 32 } 33 }; 34 35 this.autoComplete = new autoComplete({ 36 selector: () => input, 37 searchEngine: () => true, 38 wrapper:false, 39 data: { 40 src: async () => { 41 if (cancelController) cancelController.abort(); 42 cancelController = new AbortController(); 43 searchLine.classList.add('in-loading'); 44 let data = await this.utils.fetchJSON(input.dataset.sourceUrl + '&' + new URLSearchParams({ 45 term:this.autoComplete.input.value 46 }), { 47 signal: cancelController.signal 48 }); 49 searchLine.classList.remove('in-loading'); 50 51 return data ? data : []; 52 }, 53 keys:['value'] 54 }, 55 resultsList: { 56 class: '', 57 maxResults:20, 58 destination:() => resultWrapper, 59 position:'beforeend', 60 noResults: true, 61 element: (list, data) => { 62 if (!data.results.length) { 63 const message = document.createElement("li"); 64 message.setAttribute("class", "no_result"); 65 message.innerHTML = lang.t('ÐиÑего не найдено по ваÑÐµÐ¼Ñ Ð·Ð°Ð¿ÑоÑÑ'); 66 list.appendChild(message); 67 } 68 }, 69 }, 70 resultItem: { 71 element: (element, data) => { 72 let tpl; 73 74 if (data.value.type === 'product') { 75 tpl = `<a class="dropdown-item header-search__item" href="${data.value.url}"> 76 <div class="header-search__item-image"> 77 <img src="${data.value.image}"> 78 </div> 79 <div class="header-search__item-content"> 80 <div>${data.value.label}</div> 81 <div><strong>${data.value.price}</strong></div> 82 </div> 83 </a>`; 84 } 85 else { 86 let types = { 87 'category': lang.t('ÐаÑегоÑиÑ: '), 88 'brand': lang.t('ÐÑенд: ') 89 }; 90 let typeAsString = types[data.value.type] ? types[data.value.type] : ''; 91 92 if (data.value.label == 'ÐоказаÑÑ Ð²Ñе ÑоваÑÑ') { 93 tpl = `<a href="{data.value.url}" class="btn">${typeAsString}${data.value.label}</a>` 94 } else { 95 tpl = `<a class="dropdown-item" href="${data.value.url}"> 96 <div class="col">${typeAsString}${data.value.label}</div> 97 </a>`; 98 } 99 } 100 101 element.innerHTML = tpl; 102 }, 103 selected: 'selected' 104 }, 105 events: { 106 input: { 107 selection: (event) => { 108 if (event.detail.selection.value) { 109 input.removeEventListener('keyup', onEnter); 110 location.href = event.detail.selection.value.url; 111 } 112 } 113 } 114 } 115 }); 116 117 input.addEventListener('keyup', onEnter); 118 119 } 120 } 121};
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.