front_fields_sort.js

import { _x } from '@wordpress/i18n';

const findstr = window.findstr || {};
import TomSelect from 'tom-select';
import 'tom-select/src/scss/tom-select.default.scss';

document.addEventListener('findstrLoaded', function (e) {
	/**
	 * Add the sort field to the search form
	 */
	findstr.hooks.addAction('searchResultsFirstLoad', 'findstr-search', () => {
		const sortFields = document.querySelectorAll(
			'.findstr-field.findstr-field-sort'
		);

		sortFields.forEach((fieldItem) => {
			const field = JSON.parse(fieldItem.dataset.field);

			const options = [];
			const sortableFields = field.options?.sortableFields;
			if (!sortableFields) {
				return;
			}
			field.options.sortableFields.map((option) => {
				option = option.split('/').slice(-1)[0]; // Get the last part of the string (avoid tax/ or pm/ etc)
				options.push({
					value: `{"${option}":"asc"}`,
					direction: 'asc',
					/**
					 * Filter the sort label
					 *
					 * @hook findstrSortLabel
					 *
					 * @param {string} label - The label
					 * @param {string} option - The option
					 * @param {string} direction - The direction
					 * @param {object} field - The field object
					 *
					 * @returns {string} The label
					 */
					text: findstr.hooks.applyFilters(
						'findstrSortLabel',
						`${option} (asc)`,
						option,
						'asc',
						field
					),
				});
				options.push({
					value: `{"${option}":"desc"}`,
					direction: 'desc',

					/**
					 * Filter the sort label
					 *
					 * @hook findstrSortLabel
					 *
					 * @param {string} label - The label
					 * @param {string} option - The option
					 * @param {string} direction - The direction
					 * @param {object} field - The field object
					 *
					 * @returns {string} The label
					 */
					text: findstr.hooks.applyFilters(
						'findstrSortLabel',
						`${option} (desc)`,
						option,
						'desc',
						field
					),
				});
			});

			new TomSelect(
				fieldItem.querySelector('.findstrFieldContainer input'),
				{
					maxItems: 1,
					options: options,
					plugins: {},
					persist: false,
					sortField: { field: 'text' },
					render: {
						item: function (data, escape) {
							return `<div class="findstr-sort-selected findstr-sort-direction-${
								data.direction
							}">${escape(data.text)}</div>`;
						},
						option: function (data, escape) {
							return `<div class="findstr-sort-option findstr-sort-direction-${
								data.direction
							}">${escape(data.text)}</div>`;
						},
					},
				}
			);
		});
	});

	/**
	 *  Add sort to the search query
	 */
	findstr.hooks.addFilter(
		'findstrBuildSearchQuery',
		'findstr-search',
		(query, items) => {
			for (const [filter_name, inputs] of Object.entries(items)) {
				inputs.forEach((input) => {
					if (
						input.dataset.fieldType === 'sort' &&
						input.value.length > 0
					) {
						query.sort = JSON.parse(input.value);
					}
				});
			}
			return query;
		}
	);

	/**
	 * Reset Filters
	 */
	findstr.hooks.addAction('resetFilters', 'dropdownField', (group, query) => {
		findstr.groups[group].items.forEach((item) => {
			if ('sort' === item.field.type && item.tomselect) {
				const targetValue = query.sort;
				item.tomselect.clear(true);
				item.tomselect.addItem(JSON.stringify(targetValue), true);
			}
		});
	});
});