jQuery - Dynamically Create Button and Attach Event Handler
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);
});
Comments
-
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 almost 13 yearsthere's no need to
.end()
that chain. -
Alnitak almost 13 yearsFWIW, 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 almost 13 yearsIt is. find('button') will return just button element, but you need whole tr>td>button structure :)
-
Alnitak almost 13 yearsah - I see - to ensure that the returned value is the
<tr>
itself? Useful :) -
Matt Ball almost 13 yearsEither way works just fine. I can show how do it with chaining as well.
-
struppi almost 13 years@Matt Ball: Why is a terminal
end()
ever necessary? -
struppi almost 13 yearsOh, never mind. It's only useless at the end if you don't care about the returned value.
-
Alnitak almost 13 yearsit makes more sense now you've added the extra attributes