6

I am trying to fire JQuery when I checkbox is checked. At first I realized my JQuery only works for static elements. I read through a couple posts and found out that I need .on("click, function()) in order to fire that same piece of javascript for dynamically added elements.

However, this method still doesn't work for me. Can anyone help? Thank you.

$(document).ready(function(){
    $("input[name='todo']").on('click', function(){
    var isChecked = this.checked
           if (isChecked == true){
          $(this).next().remove();
          $(this).remove(); 
        }
        if (isChecked == false)
        {
        alert("checkbox is NOT checked");
        }

        });

    });

My example app: http://jsfiddle.net/JSFoo/7sK7T/8/

CYC0616
  • 645
  • 3
  • 9
  • 14
  • possible duplicate of [jQuery - Click event doesn't work on dynamically generated elements](http://stackoverflow.com/questions/6658752/jquery-click-event-doesnt-work-on-dynamically-generated-elements) – Ram Oct 04 '13 at 23:47
  • 3
    What the answers below are implying is that the jQuery selector you're using needs to exist. But `.on()` also has a second parameter for a target element selector. In the case of dynamically added elements, the primary selector should be a common static (non-changing) parent element (anywhere up to `'body'` or `document` if necessary), and the second argument to `.on()` should be the selector for the dynamic target element. – David Oct 04 '13 at 23:52
  • @David: "What the answers below are implying is that the jQuery selector you're using needs to exist." --- ? **All** the answers below use delegation. Are you sure in what you said? – zerkms Oct 04 '13 at 23:58
  • @zerkms: Yes, but they don't all really explain the structure of it. I just figured I'd add to the explanation without adding a whole answer. Usually I find that people new to delegation with `.on()` can get it to work, but don't really understand why it does what it does. Just hoping to help the OP a little more. – David Oct 05 '13 at 00:01
  • _"I read through a couple posts and found out that I need `.on("click, function())`...However, this method still doesn't work"_ - Did you think of reading the actual [jQuery `.on()` documentation](http://api.jquery.com/on)? – nnnnnn Oct 05 '13 at 00:43

4 Answers4

11

You need delegation:

$('#ToDoList').on('click', "input[name='todo']", function() { ... });

http://jsfiddle.net/7sK7T/9/

Documentation: http://api.jquery.com/on/#direct-and-delegated-events

PS: the important note - you need to specify the element you're binding your handler to as close to the target elements as possible. In your case it's #ToDoList, not body or document as other answers advice.

zerkms
  • 249,484
  • 69
  • 436
  • 539
  • It's not a big deal, but any comments on -1? You might point to my mistake, if any, so that I became a better developer. – zerkms Oct 04 '13 at 23:55
  • Yeah sure, I'm not down-voting just because I answered, I down-voted because you are stating that you need to apply it to the closest element, in other words stating that our answers are incorrect when they're not. You do **not** need to apply it to the closest element, that's wrong. Other than that it's a good answer – iConnor Oct 04 '13 at 23:59
  • @Connor: so you don't think that specifying a closest element is better? Btw, I specified "to as close to the target elements as possible" - and it's not "that's wrong", it's a correct advice – zerkms Oct 05 '13 at 00:00
  • You are not saying it's better, you're saying you **need** to do that. Yes it is probably better. – iConnor Oct 05 '13 at 00:01
  • @Connor: right, you and anyone need to select the parent element as close as possible. Do you see the difference between **need** and **must**? – zerkms Oct 05 '13 at 00:01
  • need **===** required – iConnor Oct 05 '13 at 00:03
  • But anyway, I see your point. You don't like that I referred to your less optimal code and stated that explicitly. Well, have a good day. – zerkms Oct 05 '13 at 00:03
  • No, if you would have stated in your answer that "@Connor's code is less optimal, use `'ToDoList`" Then i wouldn't have downvoted. – iConnor Oct 05 '13 at 00:06
  • @Connor: well, it's not personal. I actually didn't care who you guys are who gave those not the best advices. I just pointed that every good developer need to specify that as I specified. – zerkms Oct 05 '13 at 00:08
  • And actually it's quite funny of being downvoted just because my answer is better. It's the first time for me. Thanks for the new experience. – zerkms Oct 05 '13 at 00:09
  • I didn't say my answer was better? – iConnor Oct 05 '13 at 00:10
  • @Connor: you didn't indeed. – zerkms Oct 05 '13 at 00:11
  • @Connor: no I don't admit that – zerkms Oct 05 '13 at 00:12
  • 4
    Wow. I was going to comment that "need to" is incorrect, and that "it is better to" would be correct, and then I saw the argument that you guys have already had over that very thing. I wouldn't downvote over it, but the word ["need"](http://dictionary.reference.com/browse/need?s=t) means "requirement", that is, something that _must_ be there in order for it to work. Putting the handler on an element close to the target is definitely better, that is good advice, but it's not something you _need_ to do. – nnnnnn Oct 05 '13 at 00:57
  • @nnnnnn Ha, well I downvoted because **need** is incorrect and also Implies that the other answers are **Incorrect** – iConnor Oct 05 '13 at 01:25
  • Thanks for all the inputs! – CYC0616 Oct 05 '13 at 01:33
  • I did try to add a selector there but the one I added was simply the same as the one before "input[name='todo'] and obviously this didn't work. I did not think of adding the listID. – CYC0616 Oct 05 '13 at 01:36
  • @iConnor going by your logic the most hideous code should be accepted (and upvoted) and not down-voted because of bad practices. The answer could've had an improvement regarding the way he stated it, but down-voting it and expecting a lesser answer to be upvoted is rather strange to me. – I try so hard but I cry harder May 16 '20 at 12:20
3

For dynamic elements you would want to do something like this

$(document).ready(function () {
    $(document).on('click', "input[name='todo']", function () {
        var isChecked = this.checked
        if (isChecked == true) {
            $(this).next().remove();
            $(this).remove();
        }
        if (isChecked == false) {
            alert("checkbox is NOT checked");
        }

    });

});

if you use it like you were before on('click') is basically the same as click(); because you are still selecting the elements required and applying the event to those elements, the way the above example works is it is only applies the event to the document then checking the selector when the event is fired.

You can also change document to a close container of the elements to be clicked if you wish.

This is called Event Delegation

jQuery Learn Event Delegation

iConnor
  • 19,997
  • 14
  • 62
  • 97
3

The below is what you needed. It is slightly different syntax

$(document).on('click', "input[name='todo']", function(){
iConnor
  • 19,997
  • 14
  • 62
  • 97
bp4D
  • 915
  • 12
  • 20
  • 1
    Connor's edit formatted the code as code. (If you click on the "edited x mins ago" link you can see what changed.) – nnnnnn Oct 05 '13 at 01:00
1

You bind the elements on document ready, it's before they're created. You have to bind AFTER their creation.

Alternatively you can bind their container on document.ready:

$("#containerDiv").on('click', "input[name='todo']", function(){
   // .... your code
});
  • "containerDiv" should be the parent element of those checkboxes, it should be in the page on document ready!
iConnor
  • 19,997
  • 14
  • 62
  • 97
benams
  • 4,308
  • 9
  • 32
  • 74