KTComponents.init() specific component!
Is there a way to initialize specific component, I work with dynamic generated components, so if I use KTComponents.init() will conflict with already created components and stop working, so I was trying to initialize a [data-kt-menu] and using new KTMenu(menuTrigger) doesn't initialize completely as all click functionality not working properly
I'm working with javascript
Replies (5)
Hi
here’s what’s happening and how to address it:
-
The menu system relies on both the correct markup and the presence of certain data attributes (like data-kt-menu, data-kt-menu-item-trigger, etc.). If your injected HTML is missing these, the menu will not behave fully.
-
If you only create a new instance with new KTMenu(element), the global event handlers may not be attached if they were never initialized on the page.
-
How to fix this without resetting all components: You need to call KTMenu.initHandlers() once per page load.
This attaches the global event handlers for all menus, including dynamically created ones.
<pre> // 1. On first page load (or after Metronic assets are loaded), call this ONCE: if (!window.KT_MENU_INITIALIZED) { KTMenu.initHandlers(); window.KT_MENU_INITIALIZED = true; } // 2. When you inject a new menu: var menuTrigger = document.querySelector(`#divbtnmessage${patientagenda} [data-kt-menu-trigger]`); if (menuTrigger) { var existingInstance = KTMenu.getInstance(menuTrigger); if (existingInstance) { existingInstance.destroy(); } new KTMenu(menuTrigger); } </pre>Hi David Polanco
Currently, Metronic does not provide a built-in way to initialize only a specific component with KTComponents.init(). The recommended approach for dynamic content is:
- Destroy any existing KTMenu instance before re-initializing:
This is the official way to re-initialize a menu on dynamic content.
-
You should not need to manually add click handlers or set positioning if the HTML and data attributes are correct and no other JS is interfering.
-
If you still need manual handlers, double-check: The menu’s parent/trigger structure matches the official demo. No custom or third-party JS is interfering with event propagation. There are no JavaScript errors in the console.
If you need further help, just let us know
I try only that code but the issue persist as doesn't work entirely it can show visually the menu but the behavior and submenu not, this is why I have to include more code for the click and the submenu itself and position on page.
If you see the code I provide had extra as your code
// Add click handler with fixed positioning
// Handle clicking outside to close
If I use only KTComponents.init() works perfectly but it will reset all my current components, and for the behaviour of my page I can't do that...
Hi David Polanco
Are you using the HTML version, or is this within a framework (React, Vue, etc.)?
Can you provide a code snippet of how you are generating the dynamic menu and initializing it?
Thanks
HTML version, I have a function depending behavior I do:
<pre> var html = `<div class="d-flex cursor-pointer" data-kt-menu-trigger="{default: 'click', lg: 'click'}" data-kt-menu-attach="parent" data-kt-menu-placement="bottom-start" data-kt-menu-offset="0px, 5px"> <a class="position-relative mt-1 text-hover-primary cursor-pointer"> <i class="fa-duotone fa-solid fa-calendar-check text-primary fs-2"></i> </a> </div> <!--begin::User account menu--> <div class="menu menu-sub menu-sub-dropdown menu-column fs-6 w-300px" data-kt-menu="true"> <!--begin::Heading--> <div class="d-flex flex-column bgi-no-repeat rounded-top px-3 py-2" > <!--begin::Title--> <div class="menu-item px-3 text-white">Calendario</div> <!--end::Title--> </div> <!--end::Heading--> <!--begin::Tab content--> <div class="scroll-y mh-325px"> </div> <div class="separator mb-2"></div> <div class="pb-2 px-3 fs-8"> <!--begin::Tab panel--> <a href="javascript:void(0);" onclick="event.stopPropagation(); actualizarcalendario('${patientagenda}')" class="text-dark text-hover-primary">Modificar el Calendario</a> <!--end::Tab panel--> </div> </div>` $('#divbtnmessage' + patientagenda).html(html) </pre>In order to work I had to do this:
<pre> var menuTrigger = document.querySelector(`#divbtnmessage${patientagenda} [data-kt-menu-trigger]`); var menuDropdown = document.querySelector(`#divbtnmessage${patientagenda} .menu-sub`); if (menuTrigger && menuDropdown) { var existingInstance = KTMenu.getInstance(menuTrigger); if (existingInstance) { existingInstance.destroy(); } var newInstance = new KTMenu(menuTrigger); // Add click handler with fixed positioning menuTrigger.addEventListener('click', function (e) { setTimeout(function () { if (menuTrigger.classList.contains('showing')) { var rect = menuTrigger.getBoundingClientRect(); menuDropdown.style.display = 'block'; menuDropdown.style.position = 'fixed'; menuDropdown.style.top = (rect.bottom + 5) + 'px'; menuDropdown.style.left = rect.left + 'px'; menuDropdown.style.zIndex = '9999'; } else { menuDropdown.style.display = 'none'; } }, 50); }); // Handle clicking outside to close document.addEventListener('click', function (e) { if (!menuTrigger.contains(e.target) && !menuDropdown.contains(e.target)) { menuDropdown.style.display = 'none'; } }); } </pre>So if that could be more simple it could be awesome