2

I've added tr and td tags to a table using append but I jQuery doesn't seem to know the dom objects are there (I thought that's what append/prepend did?). When I run the script the table row is added and the user can see it but jQuery isn't catching the click handler on the hyperlink or anything else. I've done the same thing on a different page that works great. I've included that as well. If someone could please tell me where my train of thought got derailed, I'd be much obliged. Also if I'm going about this the wrong way please let me know so I can improve.

broken code:

    $("#addAdmin").click(function(){
                $("#chosenAdmins").append('<tr id = "admin' + $("#admins").val() + '"><td align="left">' + $("#admins option:selected").text() + ' </td><td align="right"><a href="#" class = "removeAdmin" id = "ra" style = "font-size: 10px;">Remove</a></td><tr>');
    });
    $(".removeAdmin").click(function(e){
        e.preventDefault();
        alert('clicked');
        alert(this.attr(id));
    });
    <select id = "admins">
        <option value = "1">bob smith</option>
    </select> 
    <input type = "button" id = "addAdmin"/>
    <table id = "chosenAdmins" align="center" width="0%"> </table>

The similar code that works on a different page is:

    $(document).ready(function() {
        var leftData = '<div id = "l1">left Stuff</div>';
        var leftData = leftData + '<div id = "l2">left Stuff</div>';
        var rightData = '<div id = "r1">right Stuff</div>';
        var rightData = rightData + '<div id = "r2">right Stuff</div>';
        $("#selector").prepend("<div id = 'leftSelect' style = 'float:left'>"+leftData+"</div><div id = 'rightSelect' style = 'float:left'>"+rightData+"</div>");
        $("#l1").click(function(){
            $(this).hide("fast", function(){
                $(this).prependTo('#rightSelect');
                $(this).show("fast");
            });
        });
     });

<div id = "selector"> </div>
3
  • please provide a proper snippet of broken code, did you forget to include <script></script> tags? if so, what else did you "forget" to exclude? Commented Jul 3, 2012 at 17:46
  • Nothing. :) that was all of the pertinent code. Commented Jul 3, 2012 at 18:51
  • alert(this.attr(id)); was also a disaster... should have been alert($(this).attr("id")); Commented Jul 3, 2012 at 19:20

5 Answers 5

3

You are defining your event handler ($('.removeAdmin').click()) before there are any .removeAdmin elements on the page.

What you need to do is delegate your events. Assuming you're using the latest jQuery:

$("#chosenAdmins").on('click','.removeAdmin',function(e){
    e.preventDefault();
    alert('clicked');
    alert(this.attr(id));
});

This way, the event handler is attached to an element that exists, namely, the chosenAdmins table.

NOTE It is not recommended to use .live, as this attaches events to the document, and other code may inadvertantly remove these events. If you are using jQuery < 1.7, use delegate:

$("#chosenAdmins").delegate('.removeAdmin','click',function(e){
    e.preventDefault();
    alert('clicked');
    alert(this.attr(id));
});
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the quick response. Is there an advantage to using on over delegate? I'm using 1.7.2.
on is just the single function call that has taken over for bind,delegate,and live (itself a version of delegate). I don't think there is any practical difference for normal event delegation, but on is the newer syntax. on also has the easy-to-remember off function for removing event handlers.
2

.removeAdmin doesn't exist yet when the click handler is added. Try this:

$("#addAdmin").click(function(){
        var tr = $("#chosenAdmins").append('<tr id = "admin' + $("#admins").val() + '"><td align="left">' + $("#admins option:selected").text() + ' </td><td align="right"><a href="#" class = "removeAdmin" id = "ra" style = "font-size: 10px;">Remove</a></td><tr>');
        $(".removeAdmin", tr).click(function(e){
            e.preventDefault();
            alert('clicked');
            alert(this.attr(id));
        });

    });
    <select id = "admins">
        <option value = "1">bob smith</option>
    </select> 
    <input type = "button" id = "addAdmin"/>
    <table id = "chosenAdmins" align="center" width="0%"> </table>

Also, be careful of using id="ra" in your row. Since #addAdmin could potentially be clicked more than once, you could end up with multiple elements with the same ID which will make your junk FREAK OUT!

3 Comments

Thanks! Id="ra" is temporary because it was broke. I'll add the id number it the ra
This hurts my head. I like this solution though. what does jquery do with the second parameter passed (tr)? I've only ever used the basic element / style / id value.
It gives the context. Effectively, that line only matches elements with the .removeAdmin class within tr, inclusively.
1

For dynamically created elements, you need the live function:

$("#elem").live("click", function() {
    // Code here
});

Works with, click, hover and all types of functions.

http://api.jquery.com/live/

2 Comments

@Xander good point.. Still using an older jQuery. About time i'd change my scripts then
I've used delegate before and in doing so I read that live was deprecated. I'm surprised how many people still use it.
1

You've got a typo in the .append (forgot to add forward slash), fix the broken HTML and it should work:

From:

...Remove</a></td><tr>')

To:

...Remove</a></td></tr>')

4 Comments

He's right. It's not the cause of the issue you mention above, but it is an issue.
@Grinn how do you know it doesn't exist when the code he's provided is just a snippet. you're assuming the code is not wrapped inside an event. he has no <script> tag around the code so it is most probably a snippet of something larger.
Sorry if I was unclear. I was only saying that his code doesn't work for other reasons, not that he doesn't need to properly close his TR tags.
Thanks for the catch Xander, Grinn is right though it wasn't the cause of the handler problems
0

Use $(document)selector while appending dom, live and delegate not recommended. For example :

$(document).on('click','.removeAdmin',function(e){
    e.preventDefault();
     alert('clicked');
    alert(this.attr(id));
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.