New Metronic Docs!Added Integration Docs with Starter Kits Apps for Laravel, Laravel Livewire, Angular, Vue, Symfony, Blazor Server, Django & Flask & more
Browse Docs

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


Text formatting options
Submit
Here's a how to add some HTML formatting to your comment:
  • <pre></pre> for JS codes block
  • <pre lang="html"></pre> for HTML code block
  • <pre lang="scss"></pre> for SCSS code block
  • <pre lang="php"></pre> for PHP code block
  • <code></code> for single line of code
  • <strong></strong> to make things bold
  • <em></em> to emphasize
  • <ul><li></li></ul>  to make list
  • <ol><li></li></ol>  to make ordered list
  • <h3></h3> to make headings
  • <a></a> for links
  • <img> to paste in an image
  • <blockquote></blockquote> to quote somebody
  • happy  :)
  • shocked  :|
  • sad  :(

Replies (5)


Hi

here’s what’s happening and how to address it:

1. 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.

2. 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.

3. 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:

- Destroy any existing KTMenu instance before re-initializing:

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 = `<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-->
Modificar el Calendario
<!--end::Tab panel-->
</div>
</div>`

$("#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


Text formatting options
Submit
Here's a how to add some HTML formatting to your comment:
  • <pre></pre> for JS codes block
  • <pre lang="html"></pre> for HTML code block
  • <pre lang="scss"></pre> for SCSS code block
  • <pre lang="php"></pre> for PHP code block
  • <code></code> for single line of code
  • <strong></strong> to make things bold
  • <em></em> to emphasize
  • <ul><li></li></ul>  to make list
  • <ol><li></li></ol>  to make ordered list
  • <h3></h3> to make headings
  • <a></a> for links
  • <img> to paste in an image
  • <blockquote></blockquote> to quote somebody
  • happy  :)
  • shocked  :|
  • sad  :(
Text formatting options
Submit
Here's a how to add some HTML formatting to your comment:
  • <pre></pre> for JS codes block
  • <pre lang="html"></pre> for HTML code block
  • <pre lang="scss"></pre> for SCSS code block
  • <pre lang="php"></pre> for PHP code block
  • <code></code> for single line of code
  • <strong></strong> to make things bold
  • <em></em> to emphasize
  • <ul><li></li></ul>  to make list
  • <ol><li></li></ol>  to make ordered list
  • <h3></h3> to make headings
  • <a></a> for links
  • <img> to paste in an image
  • <blockquote></blockquote> to quote somebody
  • happy  :)
  • shocked  :|
  • sad  :(