import { searchResultsTemplate, ISearchResult, ISearchArgs } from './templates/search_widget_template';
declare var ajaxurl: string;
declare var jQuery: any;
declare var acfw_edit_coupon: any;
interface ISearchQueryArgs {
action: string;
term: string;
_nonce: string;
}
interface ISearchResultsCache {
term: string;
results: ISearchResult[];
}
const $ = jQuery;
let searchTimeoutState: any = null;
let searchResultsCache: ISearchResultsCache | null = null;
/**
* Trigger search event when on keyboard input.
*
* @since 1.5
*/
export function triggerSearchEvent() {
// @ts-ignore
const $button = $(this);
const $wrap = $button.closest('.search-widget');
const $input = $wrap.find('input.search-input');
const $results = $wrap.find('.search-results');
const { labels, images_url, _secure_nonce } = acfw_edit_coupon.help_modal;
const term = $input.val();
// if search input is emptied, clear state and remove results.
if (!term) {
clearTimeout(searchTimeoutState);
searchTimeoutState = null;
$results.height(0).html('');
$wrap.removeClass('show-clear');
return;
}
$wrap.addClass('show-clear');
// run search query.
doSearchQuery(
{
action: $input.data('action'),
term: $input.val(),
_nonce: _secure_nonce,
},
// callback to run before running ajax.
() => {
$results.height(35).html(`

`);
},
// callback to run to process results.
(data: ISearchResult[]) => {
if (!$wrap.hasClass('show-clear')) {
return;
}
if (data.length) {
searchResultsCache = { term, results: data };
$results.html(searchResultsTemplate(data, term));
} else {
$results.html(`${labels.search_no_results}
`);
}
// adjust the height to match the content (css transform).
$results.height($results.find('ul,.no-result').height() + 3);
}
);
}
/**
* Function that handles the search query scheduling (delay 1 second after no more keyboard inputs).
*
* @since 1.5
*
* @param {ISearchArgs} args
* @param {CallableFunction} beforeCB
* @param {CallableFunction} successCB
*/
function doSearchQuery(args: ISearchQueryArgs, beforeCB: CallableFunction, successCB: CallableFunction) {
// clear saved timeout everytime search term value is changed.
if (searchTimeoutState) {
clearTimeout(searchTimeoutState);
searchTimeoutState = null;
}
// if search term is the same from previous, then serve cached results.
if (args.term === searchResultsCache?.term) {
successCB(searchResultsCache.results);
return;
}
// schedule AJAX query after 1 second.
searchTimeoutState = setTimeout(() => {
beforeCB();
$.post(ajaxurl, args, successCB, 'json');
}, 1000);
}
/**
* Clear the search text and hide results list.
*
* @since 1.5
*/
export function clearSearchEvent() {
// @ts-ignore
const $button = $(this);
const $wrap = $button.closest('.search-widget');
const $input = $wrap.find('input.search-input');
const $results = $wrap.find('.search-results');
clearTimeout(searchTimeoutState);
searchTimeoutState = null;
$input.val('');
$results.height(0).html('');
$wrap.removeClass('show-clear');
}