front_findstr-search_src_facet.js

import { debounce } from './debounce';
import { buildSearchQuery } from './helpers';

const findstr = window.findstr || {};

const findstrInit = () => {
	const items = Object.values(findstr.groups).flatMap((group) => group.items);

	items.forEach((item) => {
		const group = item.dataset.findstrGroup;
		const isDisableSearchAsYouType = item.getAttribute('data-findstr-disable-search-as-you-type') === 'yes';
		const triggerEvent = (!isDisableSearchAsYouType || 'search' !== item.type) ? 'input' : 'keyup';
		let debounceTime = 10;
		let lastQuery = '';
		let lastGroup = '';

		if ('search' === item.type) {
			debounceTime = 250;
		}

		/**
		 * Filter the debounce time for the search field.
		 *
		 * @hook findstrDebounceTime
		 *
		 * @param {number} debounceTime - The debounce time
		 * @param {string} group        - The group name
		 * @param {Object} field        - The field object
		 * @param {Object} item         - The item object
		 *
		 * @return {number} The debounce time
		 */
		debounceTime = findstr.hooks.applyFilters(
			'findstrDebounceTime',
			debounceTime,
			group,
			item.field,
			item
		);

		item.addEventListener(
			triggerEvent,
			debounce(function (e) {
				const keyValue = e.key || null;
				const group = e.target.dataset.findstrGroup;
				// If the query is the same as the last query, don't do anything
				if (
					'search' === item.type &&
					e.target.value === lastQuery &&
					group === lastGroup &&
					keyValue !== 'Enter'
				) {
					return;
				}

				const field = JSON.parse(
					item.closest('[data-field]').dataset.field
				);

				/**
				 * Triggered when the filter events are fired, before the search is performed.
				 *
				 * @hook findstrOnFilterEvents
				 *
				 * @param {HTMLObjectElement} target - The target element
				 * @param {Object}            item   - The item object
				 * @param {string}            group  - The group name
				 * @param {Object}            field  - The field object
				 */
				findstr.hooks.doAction(
					'findstrOnFilterEvents',
					e.target,
					item,
					group,
					field
				);

				// If the search field is empty and there is only one item in the group, do not reload search results.
				if (
					'search' === item.type &&
					e.target.value.length <= 0 &&
					findstr.groups[group].items.length <= 1
				) {
					return;
				}

				findstr.search(
					'',
					buildSearchQuery(group, e.target),
					group,
					field,
					e.target,
					true,
					isDisableSearchAsYouType,
					triggerEvent,
					keyValue
				);

				lastQuery = e.target.value;
				lastGroup = e.target.dataset.findstrGroup;
			}, debounceTime).bind(this)
		);
	});

	/**
	 * Triggered when the findstr is initialized.
	 *
	 * @hook findstrInit
	 *
	 * @param {Object} findstr - The findstr object
	 */
	findstr.hooks.doAction('findstrInit', findstr);
};

export { findstrInit };