assets_js_controllers_nav-bar-controller.js

const { Controller } = require("@hotwired/stimulus");

/**
 * NavBar Stimulus Controller
 * 
 * Manages navigation bar expand/collapse state tracking and server synchronization.
 * Provides persistent navigation state across page loads by recording user
 * preferences via AJAX requests.
 * 
 * Features:
 * - Navigation expand/collapse state tracking
 * - Server-side state persistence via AJAX
 * - Automatic event listener management
 * - Dual-endpoint state recording (expand/collapse)
 * - Bootstrap navigation integration
 * 
 * Targets:
 * - navHeader: Navigation header elements with expand/collapse functionality
 * 
 * Usage:
 * <nav>
 *   <button data-nav-bar-target="navHeader" 
 *           data-expand-url="/api/nav/expand/menu1"
 *           data-collapse-url="/api/nav/collapse/menu1"
 *           aria-expanded="false">
 *     Menu Item
 *   </button>
 * </nav>
 * 
 * Required attributes on navHeader targets:
 * - data-expand-url: URL to call when navigation expands
 * - data-collapse-url: URL to call when navigation collapses
 * - aria-expanded: Current expansion state
 */
class NavBarController extends Controller {
    static targets = ["navHeader"]

    /**
     * Handle navigation header clicks
     * Records expansion state to server based on aria-expanded attribute
     * 
     * @param {Event} event - Click event from navigation header
     */
    navHeaderClicked(event) {
        var state = event.target.getAttribute('aria-expanded');

        if (state === 'true') {
            var recordExpandUrl = event.target.getAttribute('data-expand-url');
            fetch(recordExpandUrl, this.optionsForFetch());
        } else {
            var recordCollapseUrl = event.target.getAttribute('data-collapse-url');
            fetch(recordCollapseUrl, this.optionsForFetch());
        }
    }

    /**
     * Handle navigation header connection to DOM
     * Sets up click event listener for state tracking
     * 
     * @param {HTMLElement} event - Connected navigation header element
     */
    navHeaderTargetConnected(event) {
        event.addEventListener('click', this.navHeaderClicked.bind(this));
    }

    /**
     * Handle navigation header disconnection from DOM
     * Cleans up click event listener
     * 
     * @param {HTMLElement} event - Disconnected navigation header element
     */
    navHeaderTargetDisconnected(event) {
        event.removeEventListener('click', this.navHeaderClicked.bind(this));
    }

    /**
     * Configure fetch options for AJAX requests
     * Sets up headers for JSON API communication
     * 
     * @returns {Object} Fetch options object
     */
    optionsForFetch() {
        return {
            headers: {
                "X-Requested-With": "XMLHttpRequest",
                "Accept": "application/json"
            }
        }
    }
}
if (!window.Controllers) {
    window.Controllers = {}
}
window.Controllers["nav-bar"] = NavBarController;