1

I'm making a code where I add content dynamically by appending an ul element.

The thing is that if I click the dynamically created button called savePalette it doesn't work.. Although it does work for the first one, because I define the addPalette function before the click function..

From what I have read, .on() is supposed to work in these cases where dynamic content is added.

This is the HTML Structure:

<ul class="palettes">
    <li class="paletteGroup">
        <ul>
            <li class="colorpalette" style="background-color: #00c4ff;"></li>
            <li class="colorpalette" style="background-color: #00a6ff;"></li>
            <li class="colorpalette" style="background-color: #0091ff;"></li>
            <li class="colorpalette" style="background-color: #007bff;"></li>
            <li class="paletteControls">
                <button name="savePalette" class="savePalette">Save</button>
                <button name="changeName" class="changeName">Change Name</button>
            </li>
        </ul>
    </li>
</ul>

JavaScript:

function addPalette() {
        var defaultColors = ["#00c4ff", "#00a6ff", "#0091ff", "#007bff"];

        $("ul.palettes").append("<li class=\"paletteGroup\"><ul>" +
        "<li class=\"paletteControls\"><button name=\"savePalette\" class=\"savePalette\">Save</button>" +
        "<button name=\"changeName\" class=\"savePalette\">Change Name</button></li>" +
        "</li></ul></li>");
        $("li.paletteGroup:last").hide();

        for(var i = 1; i <= 4; i++) {
            var j = (4 - i);
            $("ul.palettes li.paletteGroup:last ul").prepend("<li class=\"colorpalette\" style=\"background-color:" + defaultColors[j] + "\"></li>");
        }

        $("li.paletteGroup").show("fade", 500);
    }

And then this at the top of the script tag

addPalette();

$("button[name=savePalette]").on("click", function() {
    alert("Heeeeej");
});
Jake Snake
  • 165
  • 1
  • 3
  • 8

4 Answers4

7

You have to put the selector for the dynamic element in the selector argument:

$("ul.palettes").on("click", "button[name=savePalette]", function() {
    alert("Heeeej");
});
Barmar
  • 741,623
  • 53
  • 500
  • 612
2

on() only works with dynamic elements if it's delegated :

$("ul.palettes").on("click", "button[name=savePalette]", function() {
    alert("Heeeeej");
});
adeneo
  • 312,895
  • 29
  • 395
  • 388
1

Since it is dynamically created the .on() needs a broader scope:

$('body').on("click", "button[name=savePalette]", function() {
    alert("Heeeeej");
});

Now the code will listen for button[name=savePalette] to be clicked within the <body> tag which always exists.

If you are dynamically adding ul.palettes and all of it's sub-elements then you will want to listen for a change within the body rather than within the ul

MonkeyZeus
  • 20,375
  • 4
  • 36
  • 77
1

How come it works for me? Oh yeah, instead of using

$("li.paletteGroup").show("fade", 500);

use: $("li.paletteGroup").fadeIn();

see this jsFiddle

what is sleep
  • 916
  • 4
  • 12