Source: components/instant-search/instant-search-block/instant-search-result-block-dym.js

import jQ from "jquery";

import BaseComponent from "../../base-component";
import Class from "../../../helpers/class";
import Utils from "../../../helpers/utils";
import InstantSearchEnum from "../../../enum/instant-search-enum";
import Globals from "../../../helpers/globals";
import Labels from "../../../helpers/labels";

/**
 * Instant search result - Did you mean block
 * @extends BaseComponent
 */
class InstantSearchResultBlockDym extends BaseComponent {
	/**
	 * @constructs
	 */
	constructor() {
		super();
		this.data = '';
		/**
		 * This is jQuery object and contains the DYM-DOM as well
		 * @type {Object}
		 * @default null
		 */
		this.$element = null;
	}

	/**
	 * Enum of Did you mean templates (LINK, SEPARATOR, STRONG, P)
	 * @enum {Object}
	 */
	static get tempType() {
		return {
			LINK: 'link',
			SEPARATOR: 'separator',
			STRONG: 'strong',
			P: 'p'
		}
	}

	/**
	 * Get the raw HTML template of Did you mean block
	 * @param {String} [tempType] 'link', 'separator', 'strong', 'p' or let empty to get the main template
	 * @returns {String} The raw HTML template
	 * @default DYM template
	 */
	getTemplate(tempType) {
		switch (tempType) {
			case InstantSearchResultBlockDym.tempType.LINK:
				return `
					<a href="{{url}}">{{content}}</a>
				`;
			case InstantSearchResultBlockDym.tempType.SEPARATOR:
				return `
					<span>,</span>&nbsp;
				`;
			case InstantSearchResultBlockDym.tempType.STRONG:
				return `
					<strong>{{content}}</strong>
				`;
			case InstantSearchResultBlockDym.tempType.P:
				return `
					<p>{{content}}</p>
				`;
			default:
				return `
					<li class="{{class.searchSuggestionItem}} {{class.searchSuggestion}}-dym" aria-label="Did you mean">{{dymContent}}</li>
				`;
		}
		
	}

	/**
	 * Replace the brackets in raw html template with proper values
	 * @returns {String} HTML string
	 */
	compileTemplate() {
		if (this.isShow) {
			var dymHTML = '';
			if (this.dymList != '' && this.dymList.length > 0) {
				this.dymList.forEach((dym, k) => {
					var searchLink = '/search?' + Globals.searchTermKey + '=' + Utils.encodeURIParamValue(dym);
					dymHTML += this.getTemplate(InstantSearchResultBlockDym.tempType.LINK)
						.replace(/{{url}}/g, searchLink)
						.replace(/{{content}}/g, dym);
					if (k < this.dymList.length - 1) {
						dymHTML += this.getTemplate(InstantSearchResultBlockDym.tempType.SEPARATOR);
					}
				});
			}

			// Build content
			var result = '';
			if (this.suggestQuery != Globals.currentTerm) {
				// Add not found message
				if (this.totalProduct == 0) {
					var currentTermHTML = this.getTemplate(InstantSearchResultBlockDym.tempType.STRONG).replace(/{{content}}/g, Globals.currentTerm);
					var notFound = Labels.error.noSuggestionProducts.replace(/{{ terms }}/g, currentTermHTML);
					result += '<p>' + notFound + '</p>';
				}
				// Add sugges query
				if (this.suggestQuery != '') {
					var searchLink = '/search?' + Globals.searchTermKey + '=' + Utils.encodeURIParamValue(this.suggestQuery);
					var suggestQueryLinkHTML = this.getTemplate(InstantSearchResultBlockDym.tempType.LINK)
						.replace(/{{url}}/g, searchLink)
						.replace(/{{content}}/g, this.suggestQuery);
					var suggestQuery = Labels.suggestion.suggestQuery.replace(/{{ terms }}/g, suggestQueryLinkHTML);
					result += this.getTemplate(InstantSearchResultBlockDym.tempType.P).replace(/{{content}}/g, suggestQuery);
				}
				if (dymHTML != '') {
					result += this.getTemplate(InstantSearchResultBlockDym.tempType.P)
						.replace(/{{content}}/g, Labels.suggestion.didYouMean.replace(/{{ terms }}/g, dymHTML));
				}
			}

			return this.getTemplate()
				.replace(/{{dymContent}}/g, result)
				.replace(/{{class.searchSuggestion}}/g, Class.searchSuggestion)
				.replace(/{{class.searchSuggestionItem}}/g, Class.searchSuggestionItem);
		} else {
			return '';
		}
	}

	/**
	 * Render Did you mean block
	 * @returns {Object} jQuery object
	 */
	render() {
		if (this.isShow) {
			this.$element = jQ(this.compileTemplate());
		} else {
			this.$element = null;
		}
	}

	/**
	 * Set data for Did you mean component
	 * @param {Object} data the suggestion result data
	 */
	setData(data) {
		this.data = data;
		this.isShow = false;
		if (data) {
			this.productData = Utils.getValueInObjectArray(InstantSearchEnum.ResultType.PRODUCTS, this.data);
			this.suggestQuery = Utils.getValueInObjectArray(InstantSearchEnum.ResultType.SUGGEST_QUERY, this.data);
			var totalProduct = Utils.getValueInObjectArray(InstantSearchEnum.ResultType.TOTAL_PRODUCT, this.data);
			var prevTotalProduct = Utils.getValueInObjectArray(InstantSearchEnum.ResultType.PREV_TOTAL_PRODUCT, this.data);
			this.totalProduct = (prevTotalProduct !== '' && totalProduct > 0) ? prevTotalProduct : totalProduct;
			this.dymList = Utils.getValueInObjectArray(InstantSearchEnum.ResultType.DID_YOU_MEAN, this.data);
			if (this.dymList && this.dymList.length > 0) {
					this.isShow = true;
				}
		} else {
			this.productData = [];
			this.suggestQuery = '';
			this.totalProduct = 0;
			this.prevTotalProduct = '';
			this.dymList = '';
		}
	}
}

export default InstantSearchResultBlockDym;