1

I have an accordion menu, when the link header is clicked, it loads the page with the secondary links.

When clicked the .on('click') is loaded before the HTML elements are loaded, so I have to click the link header twice to open the accordion menu.

$('.accordion-menu > li > a').on('click', function (e) {

    if ($(this).siblings('ul').length) {
        e.preventDefault();
        if ($(this).closest('li').hasClass('active')) {
            $(this).siblings('ul').slideUp('normal', function () {
                $(this).closest('li').removeClass('active');
            });
        } else {
            $(this).closest('.accordion-menu').find('> li.active ul').slideUp('normal', function () {
                $(this).closest('li').removeClass('active');
            });

            $(this).siblings('ul').slideDown('normal', function () {

            });
            $(this).closest('li').addClass('active');
        }
    }
});

HTML

When I click the header, it should load the page and add class active as below

enter image description here

But now it actually just loads the page and elements are created, class active is not added.
See below "Find Jobs"
enter image description here

So in the JQuery function ($(this).siblings('ul').length) is coming 0 first time, so no class is being added...
When I click the header second time, class is added and accordion is working fine.

I tried changing the $('.accordion-menu > li > a').on('click',function (e) { but not helping...
Tried adding the function in XSLT (end of the file), currently its in separate JS file.

Thanks

Milad Rashidi
  • 1,296
  • 4
  • 22
  • 40
Vani
  • 1,345
  • 4
  • 27
  • 48
  • Use a delegate. See [this question](http://stackoverflow.com/questions/8110934/direct-vs-delegated-jquery-on) –  Oct 07 '14 at 21:02

1 Answers1

0

Your code works but if the elements are created dynamically the event should be attached to the parent (if .accordion-menu is loaded on page load and then the links inside are added dynamically) you can make it like this: http://jsfiddle.net/56fg39he/

$('.accordion-menu').on('click', 'a', function (e) {

    if ($(this).siblings('ul').length) {
        e.preventDefault();
        if ($(this).closest('li').hasClass('active')) {
            $(this).siblings('ul').slideUp('normal', function () {
                $(this).closest('li').removeClass('active');
            });
        } else {
            $(this).closest('.accordion-menu').find('li.active ul').slideUp('normal', function () {
                $(this).closest('li').removeClass('active');
            });

            $(this).siblings('ul').slideDown('normal', function () {

            });
            $(this).closest('li').addClass('active');
        }
    }
});

If the whole accordion menu is loaded dynamically into the page you can make it like this http://jsfiddle.net/56fg39he/1/

$('body').on('click', '.accordion-menu a', function (e) {

    if ($(this).siblings('ul').length) {
        e.preventDefault();
        if ($(this).closest('li').hasClass('active')) {
            $(this).siblings('ul').slideUp('normal', function () {
                $(this).closest('li').removeClass('active');
            });
        } else {
            $(this).closest('.accordion-menu').find('li.active ul').slideUp('normal', function () {
                $(this).closest('li').removeClass('active');
            });

            $(this).siblings('ul').slideDown('normal', function () {

            });
            $(this).closest('li').addClass('active');
        }
    }
}); 

You can read more about event delegation

Bojan Petkovski
  • 6,835
  • 1
  • 25
  • 34
  • Its not working either way ..Thank u for detail example. when the title header is clicked ,the page loads and it looks like
  • Plan Your Job Search
    But it has to be display:block and class="active" for first
  • .
  • – Vani Oct 08 '14 at 14:28
  • Before clicking the title header will be like
  • Find Jobs
  • .. so when clicked it loads the page with the
      – Vani Oct 08 '14 at 14:34