jQuery slideDown not working on element with dynamically assigned id

EDIT: I cleaned up the code a bit and narrowed down the problem.

So I’m working on a WordPress site, and I’m trying to incorporate drop-downs into my menu on mobile, which means I have to use jQuery to assign classes and id’s to my already existing elements. I have this code that already works on premade HTML, but fails on dynamically created id’s.

Read More

Here is the code:

...
var menuCount = 0;
var contentCount = 0;
//find the mobile menu items
var submenus = $('[title="submenu"]');
if (submenus.length && submenus.parent('.fusion-mobile-nav-item')) {
    console.log(submenus);
    submenus.addClass('dropdown-title').append('<i id="dropdown-angle" class="fa fa-angle-down" aria-hidden="true"></i>');
    submenus.each(function() {
        $(this).attr("href", "#m" + menuCount++);
    })
    var content = submenus.parent().find('ul.sub-menu');
    content.addClass('dropdown-content');
    content.each(function() {
        $(this).attr("id", "m" + contentCount++);
    })
}

$(document).on('click', '.dropdown-title', function(e) {
    var currentAttrValue = $(this).attr('href');

    if ($(e.target).is('.d-active') || $(e.target).parent('.dropdown-title').is('.d-active')) {
        $(this).removeClass('d-active');
        $(currentAttrValue).slideUp(300).removeClass('d-open');
    } else {
        $('.dropdown-title').removeClass('d-active');
        $('.dropdown-content').slideUp(300).removeClass('d-open');
        $(this).addClass('d-active');
        console.log($(currentAttrValue));

        //THIS LINE FAILS
        $(currentAttrValue).slideDown(300).addClass('d-open');
    }

    e.preventDefault();

});

I’ve registered the elements with the class dropdown-title using $(document).on(...) but I can’t figure out what I need to do to register the elements with the custom ID’s. I’ve tried putting the event callback inside the .each functions, I’ve tried making custom events to trigger, but none of them will get the 2nd to last line of code to trigger. There’s no errors in the console, and when I console log the selector I get this:

[ul#m0.sub-menu.dropdown-content, context: document, selector: “#m0”]
0
:
ul#m0.sub-menu.dropdown-content
context
:
document
length
:
1
selector
:
“#m0”
proto
:
Object[0]

So jQuery knows the element is there, I just can’t figure out how to register it…or maybe it’s something I’m not thinking of, I don’t know.

Related posts

Leave a Reply

4 comments

  1. If you are creating your elements dynamically, you should be assigning the .on ‘click’ after creating those elements. Just declare the ‘on click’ callback code you posted after adding the ids and classes instead of when the page loads, so it gets attached to the elements with .dropdown-title class.

    Check this jsFiddle: https://jsfiddle.net/6zayouxc/

    EDIT: Your edited JS code works… There also might be some problem with your HTML or CSS, are you hiding your submenus? Make sure you are not making them transparent.

  2. You’re trying to call a function for a attribute, instead of the element. You probably want $(this).slideDown(300).addClass('d-active'); (also then you don’t need $(this).addClass('d-active'); before)

  3. Inside submenus.each loop add your callback listener.

    As you are adding the class dropdown-title dynamically, it was not available at dom loading time, that is why event listener was not attached with those elemnts.

    var menuCount = 0;
    var contentCount = 0;
    //find the mobile menu items
    var submenus = $('[title="submenu"]');
    if (submenus.length && submenus.parent('.fusion-mobile-nav-item')) {
        console.log(submenus);
        submenus.addClass('dropdown-title').append('<i id="dropdown-angle" class="fa fa-angle-down" aria-hidden="true"></i>');
        submenus.each(function() {
            $(this).attr("href", "#m" + menuCount++);
    
            // add callback here
            $(this).click( function(e) {
                var currentAttrValue = $(this).attr('href');
    
                if ($(e.target).is('.d-active') || $(e.target).parent('.dropdown-title').is('.d-active')) {
                    $(this).removeClass('d-active');
                    $(currentAttrValue).slideUp(300).removeClass('d-open');
                } else {
                    $('.dropdown-title').removeClass('d-active');
                    $('.dropdown-content').slideUp(300).removeClass('d-open');
                    $(this).addClass('d-active');
                    console.log($(currentAttrValue));
    
                    $(currentAttrValue).slideDown(300).addClass('d-active');
                }
    
                e.preventDefault();
    
            });
    
    
        })
        var content = submenus.parent().find('ul.sub-menu');
        content.addClass('dropdown-content');
        content.each(function() {
            $(this).attr("id", "m" + contentCount++);
        })
    }
    
  4. Turns out my problem is that jQuery is adding to both the mobile menu and the desktop menu, where the desktop menu is being loaded first when I search for that ID that’s the one that jQuery finds. So it turns out I was completely wrong about my suspicions.