jQuery - Dynamically Create Button and Attach Event Handler

133,018

Solution 1

Calling .html() serializes the element to a string, so all event handlers and other associated data is lost. Here's how I'd do it:

$("#myButton").click(function ()
{
    var test = $('<button/>',
    {
        text: 'Test',
        click: function () { alert('hi'); }
    });

    var parent = $('<tr><td></td></tr>').children().append(test).end();

    $("#addNodeTable tr:last").before(parent);
});

Or,

$("#myButton").click(function ()
{    
    var test = $('<button/>',
    {
        text: 'Test',
        click: function () { alert('hi'); }
    }).wrap('<tr><td></td></tr>').closest('tr');

    $("#addNodeTable tr:last").before(test);
});

If you don't like passing a map of properties to $(), you can instead use

$('<button/>')
    .text('Test')
    .click(function () { alert('hi'); });

// or

$('<button>Test</button>').click(function () { alert('hi'); });

Solution 2

Quick fix. Create whole structure tr > td > button; then find button inside; attach event on it; end filtering of chain and at the and insert it into dom.

$("#myButton").click(function () {
    var test = $('<tr><td><button>Test</button></td></tr>').find('button').click(function () {
        alert('hi');
    }).end();

    $("#nodeAttributeHeader").attr('style', 'display: table-row;');
    $("#addNodeTable tr:last").before(test);
});

Solution 3

Your problem is that you're converting the button into an HTML snippet when you add it to the table, but that snippet is not the same object as the one that has the click handler on it.

$("#myButton").click(function () {
    var test = $('<button>Test</button>').click(function () {
        alert('hi');
    });

    $("#nodeAttributeHeader").css('display', 'table-row'); // NB: changed

    var tr = $('<tr>').insertBefore('#addNodeTable tr:last');
    var td = $('<td>').append(test).appendTo(tr);
});
Share:
133,018
senfo
Author by

senfo

Sr. Software Engineer from Columbia, MD.

Updated on July 09, 2022

Comments

  • senfo
    senfo almost 2 years

    I would like to dynamically add a button control to a table using jQuery and attach a click event handler. I tried the following, without success:

    $("#myButton").click(function () {
        var test = $('<button>Test</button>').click(function () {
            alert('hi');
        });
    
        $("#nodeAttributeHeader").attr('style', 'display: table-row;');
        $("#addNodeTable tr:last").before('<tr><td>' + test.html() + '</td></tr>');
    });

    The above code successfully adds a new row, but it doesn't handle adding the button correctly. How would I accomplish this using jQuery?

  • Alnitak
    Alnitak almost 13 years
    there's no need to .end() that chain.
  • Alnitak
    Alnitak almost 13 years
    FWIW, I don't like the way you've done click as an extension to the element creation - I think .click() is more intuitive, and better documented.
  • Schovi
    Schovi almost 13 years
    It is. find('button') will return just button element, but you need whole tr>td>button structure :)
  • Alnitak
    Alnitak almost 13 years
    ah - I see - to ensure that the returned value is the <tr> itself? Useful :)
  • Matt Ball
    Matt Ball almost 13 years
    Either way works just fine. I can show how do it with chaining as well.
  • struppi
    struppi almost 13 years
    @Matt Ball: Why is a terminal end() ever necessary?
  • struppi
    struppi almost 13 years
    Oh, never mind. It's only useless at the end if you don't care about the returned value.
  • Alnitak
    Alnitak almost 13 years
    it makes more sense now you've added the extra attributes