import $ from 'jquery'; const maxTextLength = 48; let lastReqId = ""; export class IHKSearchTiles { constructor(tileWrapper) { this.tileWrapper = tileWrapper.addClass("initiated"); this.itemTitles = tileWrapper[0].getElementsByTagName('a'); // eslint-disable-next-line no-control-regex const regex = new RegExp("^[a-zA-Z0-9äÄöÖüÜß._\b ]+$"); this.shortenTileText(this.itemTitles); // find input element this.formAction = tileWrapper.siblings("form")[0]; this.input = this.formAction.querySelector(".search-field"); if (!this.input) { return; } this.objId = this.input.getAttribute("data-tile-search"); this.searchButton = this.formAction.querySelector("button"); // if we have no object id configured we do not want to perform a dynamic search if (this.objId == null || this.objId.trim().length === 0 || this.formAction == null) { return; } this.rateLimit = this.checkRateLimit(this.input.getAttribute("data-tile-search-rl")); // create the search button under the tiles this.allResultButton = document.createElement("span"); this.allResultButton.classList.add("all-button-wrapper"); this.buttonString = '
Alle Suchergebnisse
'; this.allResultButton.innerHTML = this.buttonString; this.allResultButton.addEventListener("click", () => { this.searchButton.click(); }); const tiles = tileWrapper[0].innerHTML; let coolDown = false; let sendValue = ""; let lastValue = ""; let lastSend = null; this.doAjaxCall.bind(this); this.shortenTileText.bind(this); this.input.addEventListener("keyup", (event) => { if (!regex.test(event.key)) { return; } // read the current value from the input field let input = event.target; let currentText = input.value; let self = this; let delta = (lastSend === null) ? this.rateLimit + 1 : new Date().getTime() - lastSend.getTime(); if (!coolDown && currentText.length > 1) { if (delta > this.rateLimit) { sendValue = currentText; // trigger the ajax call and the search action here this.doAjaxCall(input, sendValue, this.tileWrapper[0]); lastSend = new Date(); coolDown = true; } setTimeout(() => { coolDown = false; if (lastValue !== sendValue && lastValue.length > 1) { self.doAjaxCall(input, lastValue, this.tileWrapper[0]); sendValue = lastValue; lastSend = new Date(); } }, this.rateLimit); } else if (currentText.length < 2) { // show initial tiles here let span = this.tileWrapper.nextElementSibling; this.tileWrapper.innerHTML = tiles; if (span) { span.remove(); } } lastValue = currentText; }); // remove initial search input in case of the user uses the back function of the browser window.onload = () => { this.input.value = ""; }; } shortenTileText(tiles) { for (let tile of tiles) { if (tile.innerText.length > maxTextLength) { tile.innerText = tile.innerText.substring(0, maxTextLength) + '…'; } } } doAjaxCall(ajaxObj, query, tiles) { const self = this; const objId = ajaxObj.getAttribute("data-tile-search"); const url = "/blueprint/servlet/serviceport/search/" + objId; const urlAndQuery = url + "?query=" + query; const requestId = Math.floor(Math.random() * 100000); lastReqId = requestId; $.ajax({ url: urlAndQuery, method: "GET", timeout: 0, success: function (result) { if (requestId === lastReqId) { // replace tiles here tiles.innerHTML = result; // find tile a and shorten the text if needed let itemTitles = tiles.getElementsByClassName('item-title'); self.shortenTileText(itemTitles); // add the "all results" button tiles.insertAdjacentElement("afterend", self.allResultButton); } } }); } checkRateLimit(rl) { if (rl.trim().length > 0) { let num = parseInt(rl); if (num >= 100) { return num; } else { return 300; } } return 300; } } class IHKExtendedSearch { constructor(section) { this.section = section.addClass('initiated'); $('#search-expand-collapse').on('click', (e) => { e.preventDefault(); $(e.currentTarget).toggleClass('open'); this.section.stop().slideToggle(500, 'swing'); }); section.find('.ev-search-btn').on('click', (e) => { e.preventDefault(); const target = $(e.currentTarget); target.next('.ev-filter').stop().slideToggle(400, 'easeOutQuad'); window.requestAnimationFrame(() => { target.toggleClass('open'); }) }); section.find('label.acc a').each((i, el) => { new FormAccordion($(el)); }); section.find('.reset').on('click', (e) => { e.preventDefault(); const form = $(e.currentTarget).closest('form'); form[0].reset(); form.find('.half-checked').removeClass('half-checked'); $('html, body').animate({ scrollTop: form.offset().top - 120 }, 500, 'easeOutQuad'); }); /* $('.datepicker').each((i, el) => { $(el).datepicker({ changeYear: true, changeMonth: true}); }); */ } } class FormAccordion { constructor(toggle) { this.toggle = toggle; this.label = this.toggle.parent('label'); this.checkbox = this.label.prev('input[type="checkbox"]'); this.subs = this.label.next('.ev-filter'); this.toggle.on('click', (e) => { e.preventDefault(); e.stopPropagation(); this.label.toggleClass('open'); this.subs.stop().slideToggle(400, 'swing'); }) this.subs.find('input[type="checkbox"]').on('change', () => { this.checkSelection(); }) this.checkbox.on('change', (e) => { const isChecked = $(e.currentTarget).removeClass('half-checked').prop('checked'); this.subs.find('input[type="checkbox"]').prop('checked', isChecked); }) this.checkSelection(); } checkSelection() { const checked = this.subs.find('input[type="checkbox"]:checked').length; const unchecked = this.subs.find('input[type="checkbox"]:not(:checked)').length; if (checked + unchecked === 0) { this.checkbox.removeClass('half-checked'); return; } if (checked === 0) { this.checkbox.prop('checked', false).removeClass('half-checked'); } else if (unchecked === 0) { this.checkbox.prop('checked', true).removeClass('half-checked'); } else { this.checkbox.prop('checked', false).addClass('half-checked'); } } } export default IHKExtendedSearch; $('body').on('ihk-init dynamic-component-loaded', function () { $('.extended-search:not(.initiated)').each(function () { new IHKExtendedSearch($(this)); }); });