Get 2024 Templates Mega Bundle!14 Bootstrap, Vue & React Templates + 3 Vector Sets
Get for 99$

Ajax fetched static menu content stopped working and triggering for menu-item menu-accordion


Hello,
I decided to keep my 'long' menu items in a separate html file for static front-end project and show menu items by fetching them with ajax with this js code:
// Function to load the sidebar menu content from external file: kt_app_sidebar_menu.html
function loadSidebar() {
const sidebarContainer = document.getElementById('kt_app_sidebar-temp');

if (sidebarContainer) {
fetch('kt_app_sidebar_menu.html')
.then(response => response.text())
.then(content => {
sidebarContainer.innerHTML = content;
})
.catch(error => {
console.error('Error loading sidebar:', error);
});
} else {
console.error('Sidebar container element not found.');
}
}
// Call the function to load the sidebar when the page loads.
window.addEventListener('DOMContentLoaded', loadSidebar);


I left only a container with ID specified in the js code.

When the data-kt-menu-trigger="click" class="menu-item menu-accordion" stops opening the accordion I click the menu that has no sub items then other menu group with menu items starts working by opening the accordion.

Is there a way to fix this issue? I tried api but could not resolve the issue.
your helper apis

Here is the fetched menu.


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 (10)


I solved the issue by creating instances function, thank you.
/ Function to load the sidebar menu content from external file: kt_app_sidebar_menu.html
function loadSidebar() {
const sidebarContainer = document.getElementById('kt_app_sidebar_menu');

if (sidebarContainer) {
fetch('kt_app_sidebar_menu.html')
.then(response => response.text())
.then(content => {
sidebarContainer.innerHTML = content;

// Initialize KT Menu instances
KTMenu.createInstances();

})
.catch(error => {
console.error('Error loading sidebar:', error);
});
} else {
console.error('Sidebar container element not found.');
}
}
// Call the function to load the sidebar and initialize KeenThemes Menu instances when the page loads.
window.addEventListener('DOMContentLoaded', loadSidebar);



Hi,

Right approach. Glad to see that you fixed it.

As explained in the Docs for any dynamically loaded content, you can also use KTComponents.init() to initialize all the newly populated core components including KTMenu.

Regards.



Thank you! Now I have issue related adding 'active' class to current menu item a class="menu-link" and also to its parent span class="menu-link". It's currently a html page but I'm sure it can be done with JS.
Here is my js code, maybe I miss something from the Docs. Can you please guide me to resolve the issue!

// Function to load the sidebar menu content from an external file: kt_app_sidebar_menu.html
function loadSidebar() {
const sidebarContainer = document.getElementById('kt_app_sidebar_menu');

if (sidebarContainer) {
fetch('kt_app_sidebar_menu.html')
.then(response => response.text())
.then(content => {
sidebarContainer.innerHTML = content;

// Initialize KT Menu instances
KTMenu.createInstances();

// Get the current URL
const currentURL = window.location.href;

// Select all menu links
const menuLinks = document.querySelectorAll('.menu-link');

// Iterate through the menu links and check if their href matches the current URL
menuLinks.forEach(link => {
const href = link.getAttribute('href');
if (href === currentURL) {
link.classList.add('active');

// If this is a submenu link, also add 'active' class to its parent menu item
const menuItem = link.closest('.menu-item');
if (menuItem) {
menuItem.querySelector('.menu-link').classList.add('active');
}
}
});
})
.catch(error => {
console.error('Error loading sidebar:', error);
});
} else {
console.error('Sidebar container element not found.');
}
}

// Call the function to load the sidebar when the page loads.
window.addEventListener('DOMContentLoaded', loadSidebar);



Hi,

Please try to use the below API as shown here


KTMenu.updateByLinkAttribute("/users/group/add", "href");


Regards.



Yes I noticed that function in APIs and then tried but it can not add active classes to current link:
// Function to load the sidebar menu content from an external file: kt_app_sidebar_menu.html
function loadSidebar() {
const sidebarContainer = document.getElementById('kt_app_sidebar_menu');

if (sidebarContainer) {
fetch('kt_app_sidebar_menu.html')
.then(response => response.text())
.then(content => {
sidebarContainer.innerHTML = content;

// Initialize KT Menu instances
KTMenu.createInstances();
KTComponents.init();

// Use KTMenu.updateByLinkAttribute to set the active link based on the "href" attribute
const currentURL = window.location.pathname; // Use pathname to get the current URL
KTMenu.updateByLinkAttribute(currentURL, 'href');
})
.catch(error => {
console.error('Error loading sidebar:', error);
});
} else {
console.error('Sidebar container element not found.');
}
}

// Call the function to load the sidebar when the page loads.
window.addEventListener('DOMContentLoaded', loadSidebar);



Hi,

What is the actual value of currentURL ? Can you test your code with the actual URL and make sure the URL matches the href value in the menu? If the URL and href match then it should work as expected.

Regards.



Hello, thank you for your reply!
Here is my a code snippet of the fetched html menu content inside 'kt_app_sidebar_menu.html' and I don't know do I have to add absolute or full path:
<div class="menu-item">
<a class="menu-link" href="index.html">
<span class="menu-icon">
<i class="las la-home fs-2"></i>
</span>
<span class="menu-title">Anasayfa</span>
</a>
</div>
<div class="menu-item seperator mb-1"></div>
<!--begin:menu item group-->
<div data-kt-menu-trigger="click" class="menu-item menu-accordion">
<span class="menu-link">
<span class="menu-icon">
<i class="las la-bell fs-2"></i>
</span>
<span class="menu-title">Talepler</span>
<span class="menu-arrow"></span>
</span>
<div class="menu-sub menu-sub-accordion">
<div class="menu-item">
<a class="menu-link" href="addRequest.html">
<span class="menu-bullet">
<span class="bullet bullet-vertical"></span>
</span>
<span class="menu-title">
Yeni Talep Ekle</span>
<!-- <span class="menu-badge">
<span class="badge badge-light-success">3</span>
</span> -->
</a>
</div>
<div class="menu-item">
<a class="menu-link" href="requestListAll.html">
<span class="menu-bullet">
<span class="bullet bullet-vertical"></span>
</span>
<span class="menu-title">Tüm Talepler</span>
</a>
</div>
<div class="menu-item">
<a class="menu-link" href="requestListUnassigned.html">
<span class="menu-bullet">
<span class="bullet bullet-vertical"></span>
</span>
<span class="menu-title">GönderilmemiÅŸ Talepler</span>
</a>
</div>
</div>
</div>


I tried to assign 'active' class referencing only the html file name but not resolved the issue:

// Function to load the sidebar menu content from an external file: kt_app_sidebar_menu.html
function loadSidebar() {
const sidebarContainer = document.getElementById('kt_app_sidebar_menu');

if (sidebarContainer) {
fetch('kt_app_sidebar_menu.html')
.then(response => response.text())
.then(content => {
sidebarContainer.innerHTML = content;

// Initialize KT Menu instances
KTMenu.createInstances();
KTComponents.init();

// Get the current URL
const currentURL = window.location.pathname; // Use pathname to get the current URL

// Function to extract the file name from a URL
function getFileNameFromURL(url) {
const parts = url.split('/');
return parts.pop(); // Get the last part (file name)
}

// Select all menu links
const menuLinks = sidebarContainer.querySelectorAll('.menu-link');

// Update active links based on the "href" attribute using KTMenu.updateByLinkAttribute
menuLinks.forEach(link => {
const href = link.getAttribute('href');
const fileName = getFileNameFromURL(href);

// Check if this link matches the current URL's file name
if (fileName === getFileNameFromURL(currentURL)) {
KTMenu.updateByLinkAttribute(href, 'href');

// If this is a submenu link, also add 'active' class to its parent menu item
const menuItem = link.closest('.menu-item');
if (menuItem) {
menuItem.querySelector('.menu-link').classList.add('active');
}
}
});
})
.catch(error => {
console.error('Error loading sidebar:', error);
});
} else {
console.error('Sidebar container element not found.');
}
}

// Call the function to load the sidebar when the page loads.
window.addEventListener('DOMContentLoaded', loadSidebar);



Hi,

Please understand how KTMenu.updateByLinkAttribute(url, "href") works. It looks for a menu link with href="{url}" and if matches it will set the active state to that menu link. Please make sure that the value u pass as the URL match the menu links href value.

Regards.



Thank you, I see happy You are awesome!
Can you please add letter 's' here. It took 13 min. of my time happy

Dimiss Options


data-bs-dimiss="click"

it should be
data-bs-dismiss="click"

My best wishes to you guys!

Hi happy,

Sure, we will update it. Appreciate your feedback.

If you liked Keen and would love to support it could you please consider leaving a 5-star review here: https://themes.getbootstrap.com/product/keen-the-ultimate-bootstrap-admin-theme/

Regards.


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  :(