HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/egovers/edwingovers.nl/resources/assets/js/kms/entity/tabs.js
class TabsController {

    /**
     * The tab controller can obviously control tabs.
     * You just have to have a couple of divs that hold the content. These divs must all have a class name that
     * corresponds to the value of constructor parameter tabContentIdAndClassAndPrefix. And they all must have an id
     * that also starts with the value of tabContentIdAndClassAndPrefix followed by the tab slug.
     *
     * You can specify if you have an hidden input field that needs to be updated with the curent tab slug. You do that
     * with the tabSlugInputSelector.
     *
     * Content tab divs and buttons will also receive an active state class to make them visible / stand out when present
     * or hidden / to background. You can specify this class name with the activeClass parameter.
     *
     * The tabButtonGroupSelector selects an element that holds the tab buttons to switch tabs. This element must have an
     * ul element that holds li elements containing a elements.
     *
     * The reactToUrlHashChange parameter controls if the controller should react if the hash part of the url did change.
     *
     * @param tabContentIdAndClassAndPrefix stringseelc
     * @param tabButtonGroupSelector string
     * @param activeClass string
     * @param reactToUrlHashChange
     * @param tabSlugInputSelector string
     */
    constructor(tabContentIdAndClassAndPrefix = 'tab', tabButtonGroupSelector = '.tab-buttons', activeClass = 'active', reactToUrlHashChange = false, tabSlugInputSelector = undefined) {
        this.tabContentDivsClassAndIdPrefix = tabContentIdAndClassAndPrefix;
        this.tabSlugInputId = tabSlugInputSelector;
        this.activeClass = activeClass;
        this.reactToUrlHashChange = reactToUrlHashChange;

        if(reactToUrlHashChange) this.addListenerForHashChange(reactToUrlHashChange);
    }

    /**
     * Opens the tab by using the tab slug
     *
     * @param tabSlug
     */
    openTab(tabSlug) {
        //Remove trailing / on the left hand side
        tabSlug = this.removeLeftHandSlashInSlug(tabSlug);
        if (!tabSlug) { console.error("TabsController: Could not open tab with an empty slug"); return; }

        this.updateTabSlugInput(tabSlug);

        this.showTabContentForTabWithSlug(tabSlug);
        this.makeTabButtonActiveForSlug(tabSlug);
    }

    /**
     * Removes a / at the beginning of a tab slug
     *
     * @param tabSlug
     */
    removeLeftHandSlashInSlug(tabSlug) {
        return tabSlug.replace(/^\/(.*)/, '$1');
    }

    /**
     * Updates a usually hidden input field holding the tab slug with a new slug
     *
     * @param newSlug string
     */
    updateTabSlugInput(newSlug)
    {
        if(this.tabSlugInputId === undefined) return;
        let element = document.querySelector(this.tabSlugInputId);
        if(element) element.value = newSlug;
    }

    makeTabButtonActiveForSlug(slug)
    {
        $('.entity-tabs >ul >li').removeClass('active');
        $('.entity-tabs >ul >li a[href="#' + slug + '"]').parent().addClass('active');
    }

    /**
     * Shows the tab content div with the specified slug and hides the other content div tabs.
     * It does this by adding and removing classes (the active class you specified in the constructor)
     *
     * @param slug string
     */
    showTabContentForTabWithSlug(slug)
    {
        //Remove the active class from all tab content classes
        document.querySelectorAll('.'+this.tabContentDivsClassAndIdPrefix).forEach((element) => {
            element.classList.remove(this.activeClass)
        });

        //Add the active class to the tab that has the correct slug appended to the IdPrefix
        let activeTab = document.querySelector("#"+this.tabContentDivsClassAndIdPrefix+"-"+slug);
        if(!activeTab) { console.error("TabsController: Could not make content tab active. It should have an ID with: #"+this.tabContentDivsClassAndIdPrefix+"-"+slug); return; }

        activeTab.classList.add(this.activeClass);
    }

    /**
     * Adds or disables listening for hashchange events to update tabs
     *
     * @param boolean
     */
    addListenerForHashChange(boolean)
    {
        if(boolean) {
            window.addEventListener('hashchange', this.hashChanged.bind(this));
            window.addEventListener('load', this.hashChanged.bind(this));
        } else {
            window.removeEventListener('hashchange', this.hashChanged);
            window.removeEventListener('load', this.hashChanged);
        }
    }

    /**
     * Called automatically by an internal listener (controlled by the addListenerForHashChange method)
     */
    hashChanged(event)
    {
        let tabSlug = window.location.hash.substring(1);
        if (tabSlug) {
            this.openTab(tabSlug);
            return;
        }

        let tabSlugElement = document.querySelector(this.tabSlugInputId);
        if(!tabSlugElement) return;

        this.openTab(tabSlugElement.value);
    }
}