-1

I am currently working on a website that has a logout button which gets dynamically inserted into a sidebar whenever the window reaches a certain size. When I click on the log out button I want to call the method logOut();

I looked over these other posts and the solutions don't seem to be working for me. The method gets called if I click on the element while it's on the main page, but when I resize the window and the element gets "re-added" to the webpage it doesn't do anything (The ID selector is the right one because the style is all there).

$(document).ready(function()
{
    $(document).on("click", "#btnLogOut", function()
    {
        logOut();
    });
});

I expected the logOut() method to be called after clicking on the anchor tag, but it doesn't do anything even if the .on() method is supossed to take care of dynamically created elements

EDIT: This is how I re-add the element to the page after resizing. The nav element that includes the logout anchor tag is made into a list by a navList(); method and then gets appended to the body. I made sure to specify that the logout button needs to keep its ID. Only going to add the code relevant to the log out button.

$.fn.navList = function() {

    var $this = $(this);
        $a = $this.find('a'),
        b = [];

    $a.each(function() {

        var $this = $(this),
            indent = Math.max(0, $this.parents('li').length - 1),
            href = $this.attr('href'),
            target = $this.attr('target');
        if($a.attr("id") === "btnLogOut") {
            console.log($a);
            b.push(
                '<a ' +
                    'id="btnLogOut" ' + 
                    'class="link depth-' + indent + '"' +
                    ( (typeof target !== 'undefined' && target != '') ? ' target="' + target + '"' : '') +
                    ( (typeof href !== 'undefined' && href != '') ? ' href="' + href + '"' : '') +
                '>' +
                    $this.text() +
                '</a>'
            );
        }

    });

    return b.join('');

};
            $(
                '<div id="navPanel">' +
                    '<nav>' +
                        $('#btns').navList() +
                    '</nav>' +
                '</div>'
            )
                .appendTo($body)
Peki
  • 25
  • 6

1 Answers1

0

Let not your heart be troubled, jQuery .on() absolutely works with a dynamically-injected element. So, what could be causing it to not work in this instance?

First, most common, cause: spelling and/or capitalization. Did you not capitalize one of the characters? For e.g. #btnLogOut is not the same as #btnLogout

Second, equally common error: duplicate IDs on the page. Change the ID for the button you want and test again (add the three-character suffix _zq to the end of the ID - a suitably unlikely string suffix - and remember to change both the HTML ID and the ID referenced by jQuery).

Sometimes, you just need to be more specific. Instead of #btnLogOut, try adding some parent IDs and classes. If, for example, this was your structure:

<div class="row bob">
    <div class="container sam ed tom">
        <div class="dialog frank lg pc6">
            <div class="dlg-bottom">
                <button id="btnLogOut">Log Out</button>

then make your jQuery statement:

$(document).on('click', '.row .container .dialog .dig-bottom #btnLogOut', function(){
    //code goes here
});

How to test what you have:

At the point where the button has been been added to the page and is visible on screen:

  1. Right-Click on the button, choose Inspect Element from the pop-up menu

  2. Chrome's DevTools will open

  3. If the console is not visible as the bottom half of the DevTools window, press Esc

  4. In the console input area, type: $('#btnLogOut').length

You should see the number 1 appear below that line.

If you get the message Uncaught TypeError: $ is not a function, then you should first inject jQuery into DevTools and try step 4 again.

cssyphus
  • 37,875
  • 18
  • 96
  • 111
  • 1. The ID is btnLogOut everywhere (even checked it by searching in my IDE in case there are any invisible characters or somehting). 2. There is always only one log out anchor tag on every page. To be sure, I replaced btnLogOut with btnLogOut_zq everywhere but the error persists. 3. ```$("btnLogOut").length``` returns 1 both before and after re-adding the element to the page. Thanks a lot for the help even if I didn't find the right solution yet. – Peki Jun 23 '19 at 10:44
  • If it were me, I would find DevTools to be the most useful tool for resolving this problem. At the `console` prompt, you can find out if the element exists at any given time *(and at some point it should go from a `.length` of 0 to a `.length` of 1 - at the point where the button is injected into the DOM - so you should be sure you see that transition)* Also, in DevTools, you can enter multi-line javascript *(press Ctrl+Enter after each line)* so really you can live-tweak your code until you find what works. – cssyphus Jun 23 '19 at 16:06
  • I used ```setInterval(function(){ console.log($("#btnLogOut").length); },1);``` and this returns 1 constantly while resizing the window and making it bigger and then smaller :( – Peki Jun 23 '19 at 17:52
  • So, how is it "dynamically-created" then? Usually, that means the element is loaded into the DOM *after* the DOM was initially rendered. If the element exists at initial `document.ready`, then you don't actually need to use `.on()` - simply trapping the click event should do the trick: `$('#btnLogOut').click(function(){ //your code here });` Nevertheless, it should still trap the click with `.on()`... so I am puzzled. – cssyphus Jun 23 '19 at 23:48