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
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.
// 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);
}
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:
var menuTrigger = document.querySelector(`#divbtnmessage${patientagenda} [data-kt-menu-trigger]`);
if (menuTrigger) {
var existingInstance = KTMenu.getInstance(menuTrigger);
if (existingInstance) {
existingInstance.destroy();
}
var newInstance = new KTMenu(menuTrigger);
}
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:
var html = ` ` $('#divbtnmessage' + patientagenda).html(html)
In order to work I had to do this:
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';
}
});
}
So if that could be more simple it could be awesome