(function () { window.initStagSuggest = function () { let suggestionsOuter = null; const debounce = (func, wait) => { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; }; var lastTerm = ''; var returnedFunction = debounce(function (elem) { let term = elem.val(); if (!!term && lastTerm !== term) { let ep = $(elem).attr('stag-suggest-ep'); $.get(ep + '?term=' + $.trim(term), function (_data) { /* expected return format: { success: true, data: [ { x: ..., y: ..., text: ... // "text" key is "mandatory" }, { x: ..., y: ..., text: ... // "text" key is "mandatory" }, ... ] } */ suggestionsOuter.empty(); if(!hasResponseError(_data) && _data.data && _data.data.length) { for (let i = 0; i < _data.data.length; i++) { let item = $(''); for(let x in _data.data[i]) { if(_data.data[i].hasOwnProperty(x) && x !== 'text') { item.attr('data-' + x, _data.data[i][x]); } } item.data('suggest-data', _data.data[i]); item.html(_data.data[i].text); suggestionsOuter.append(item); } } else { suggestionsOuter.html('No matches!'); } suggestionsOuter.removeClass('d-none'); }, 'json'); lastTerm = term; } else { suggestionsOuter.addClass('d-none'); } }, 250); function handleKeydown(elem, e) { let term = $.trim(elem.val()); let activeItem = suggestionsOuter.find('.suggest-item.active'); switch (e.which) { case 27: suggestionsOuter.addClass('d-none'); return false; case 38: if (activeItem.prev().length) { activeItem.prev() .addClass('active') .siblings().removeClass('active'); activeItem = suggestionsOuter.find('.suggest-item.active'); if (activeItem.length) { activeItem[0].scrollIntoView(); } } return false; case 40: if (activeItem.next().length) { activeItem.next() .addClass('active') .siblings().removeClass('active'); activeItem = suggestionsOuter.find('.suggest-item.active'); if (activeItem.length) { activeItem[0].scrollIntoView(); } } return false; case 13: if (activeItem.length) { activeItem.first().click(); } return false; default: if (!!term) { suggestionsOuter .html('Searching...') .removeClass('d-none'); returnedFunction(elem); } else { suggestionsOuter.addClass('d-none'); } break; } } function handleKeypress(elem, e) { var term = $.trim(elem.val()); if (!!term) { suggestionsOuter .html('Searching...') .removeClass('d-none'); returnedFunction(elem); } else { suggestionsOuter.addClass('d-none'); } } $('[stag-suggest]:not([stag-suggest-initialized])').each(function () { let elem = $(this); elem.next('.stag-suggestions-container').remove(); $('