Source: components/filter/filter-tree/filter-mobile-button.js

import jQ from 'jquery';

import BaseComponent from "../../base-component";
import Labels from "../../../helpers/labels";
import Settings from '../../../helpers/settings';
import FilterOptionEnum from '../../../enum/filter-option-enum';
import Class from '../../../helpers/class';

/**
 * A single filter mobile button.
 * Toggles show/hide filter tree on mobile.
 * Is rendered on DOM elements with class 'boost-pfs-filter-tree-mobile-button'
 * attribute 'data-filter-tree-id' determines which filter tree the button will be associated with. By default the button toggles the first vertical filter tree.
 * @extends BaseComponent
 */
class FilterMobileButton extends BaseComponent {
	/**
	 * Creates a mobile button to toggle a filter tree
	 * @param {FilterTree} filterTree An instance of the FilterTree class to associate the button with.
	 */
	constructor(filterTree) {
		super();
		this.filterTree = filterTree;
		this.filterTree.mobileButton = this;
		this.isCollapsed = true;
		this.label = Labels.refineMobile;

		this.$element = null;
	}

	/**
	 * Get the mobile button raw html template
	 * @returns {string}
	 */
	getTemplate() {
		return `
				<button type="button">{{label}}</button>
		`;
	}

	/**
	 * Replace the brackets in raw html template with proper values
	 * @returns {string}
	 */
	compileTemplate() {
		return this.getTemplate()
			.replace(/{{filterTreeMobileButton}}/g, Class.filterTreeMobileButton)
			.replace(/{{label}}/g, this.label);
	}

	render() {
		if (!this.$element) {
			this.$element = jQ(this.compileTemplate());
		}
		// Hide mobile button if there is no filter option
		if (this.parent.isFetchedFilterData) {
			var hasAnyFilterOption = this.filterTree.filterOptions.size > 0;

			if (!hasAnyFilterOption) {
				this.$element.hide();
			}
		}
	}

	isBindEvents() { return !this.isBoundEvent; }

	bindEvents() {
		if (this.$element && this.filterTree) {
			this.$element.on('click', this.onClick.bind(this));
		}
	}

	/**
	 * Onclick event for the mobile button
	 */
	onClick() {
		// Use onClickMobileButton function to change mobile button behavior (used in style2, style3,..)
		if (typeof this.filterTree.onClickMobileButton == 'function') {
			this.filterTree.onClickMobileButton();
		} else {
			this.toggleFilterTree();
		}
		jQ('body').toggleClass(Class.filterTreeOpenBody);
	}
	
	/**
	 * Toggles the filter tree, this function is called by 'onClick' function
	 */
	toggleFilterTree() {		
		var $toggleFilterTreeElement = jQ('#' + this.filterTree.id);
		if (!$toggleFilterTreeElement || $toggleFilterTreeElement.hasClass('toggling')) {
			return;
		}

		this.isCollapsed = !this.isCollapsed;

		if (Settings.getSettingValue('general.changeMobileButtonLabel')) {
			this.label = this.isCollapsed ? Labels.refineMobile : Labels.refineMobileCollapse;
			this.$element.text(this.label);
		}

		$toggleFilterTreeElement.slideToggle(400, this.afterToggleFilterTree.bind(this));
	}

	/**
	 * After finishing the filter tree toggle animation.
	 * Run some codes to format the sizes of box items.
	 */
	afterToggleFilterTree() {
		if (!this.isCollapsed) {
			this.filterTree.filterOptions.forEach(filterOption => {			
				if (filterOption.displayType == FilterOptionEnum.DisplayType.BOX && !filterOption.isCollapsed) {
					filterOption.filterItems.forEach(item => {
						item.setBoxItemSize();
					})
				}
			})
		}
	}
}

export default FilterMobileButton;