senfo
senfo

Reputation: 29036

jQuery - Dynamically Create Button and Attach Event Handler

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?

Upvotes: 48

Views: 143250

Answers (5)

Matt Ball
Matt Ball

Reputation: 359826

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'); });

Upvotes: 64

Alnitak
Alnitak

Reputation: 339816

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);
});

Upvotes: 8

Schovi
Schovi

Reputation: 1990

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);
});

Upvotes: 10

jnoreiga
jnoreiga

Reputation: 2175

You were just adding the html string. Not the element you created with a click event listener.

Try This:

<html>
<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
</head>
<body>
    <table id="addNodeTable">
        <tr>
            <td>
                Row 1
            </td>
        </tr>
        <tr >
            <td>
                Row 2
            </td>
        </tr>
    </table>
</body>
</html>
<script type="text/javascript">
    $(document).ready(function() {
        var test = $('<button>Test</button>').click(function () {
            alert('hi');
        });
        $("#addNodeTable tr:last").append('<tr><td></td></tr>').find("td:last").append(test);

    });
</script>

Upvotes: 0

Brett Zamir
Brett Zamir

Reputation: 14345

You can either use onclick inside the button to ensure the event is preserved, or else attach the button click handler by finding the button after it is inserted. The test.html() call will not serialize the event.

Upvotes: 0

Related Questions