2

On my page, I have a dynamically generated list of radio buttons (created with AJAX). The list of radio buttons is dynamically generated because it changes based on a previous form selection. Here is an example of a dynamically generated list of radio buttons (this appears in Firefox's DOM viewer add-on, but not in "View Page Source"):

<li>
<input name="giftcard_value" type="radio" id="25" value="25" />
<label for="25">$25</label>
<a class="radio-select" href="#">Select</a><a class="radio-deselect" href="#">Cancel</a>
</li>

<li>
<input name="giftcard_value" type="radio" id="50" value="50" />
<label for="50">$50</label>
<a class="radio-select" href="#">Select</a><a class="radio-deselect" href="#">Cancel</a>
</li>

I also have another jQuery script that I am using to "click" radio buttons indirectly via links/images. In the above code, the actual radio button (inside the input tag) is hidden from the user. The user clicks the radio button by clicking the Select link that has the class "radio-select" (this is actually an image). The jQuery script detects when the link/image is clicked with '$(".radio-select").click' and then runs a function which "clicks/checks" the actual radio button. Here is the jQuery script:

$(".radio-select").click(
            function(event) {
                event.preventDefault();
                var $boxes = $(this).parent().parent().children();
                $boxes.removeClass("selected");
                $(this).parent().addClass("selected");
                $(this).parent().find("[type=radio]").click().attr("checked","checked");
            }
        );

My problem is that the jQuery script does NOT work with the dynamically generated radio buttons. It works if I hard code the radio buttons into the html (viewable via "view page source" in a browser), but not if they're generated dynamically. It seems like the jQuery is not able to detect the ".click" on the link/image, and thus never clicks the actual radio button. Any idea what the problem is? Any help would be much appreciated!

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Stone
  • 121
  • 5
  • 14
  • This is a duplicate - http://stackoverflow.com/questions/203198/jquery-event-binding-on-dynamically-created-elements – mrtsherman Jan 05 '12 at 04:33

4 Answers4

7

check delegate and on method.

example

$("table").delegate("td", "click", function() {
  $(this).toggleClass("chosen");
});

http://api.jquery.com/delegate/

from jQuery page,

As of jQuery 1.7, .delegate() has been superseded by the .on() method. For earlier versions, however, it remains the most effective means to use event delegation

http://api.jquery.com/on/

example

$("p").on("click", function(){
alert( $(this).text() );
});
Shyju
  • 214,206
  • 104
  • 411
  • 497
  • If you are in jQuery 1.4.2+ you shouldn't be using live either. Use delegate instead. Delegate is also a good choice for jQuery 1.7+ http://api.jquery.com/delegate/ – mrtsherman Jan 05 '12 at 04:34
  • 1
    Don't use `live()`, use [`on()`](http://api.jquery.com/on/). Unless you're using a version of jQuery that's less than 1.7, then use [`delegate()`](http://api.jquery.com/delegate/). – Ayman Safadi Jan 05 '12 at 04:34
  • Thanks! I came across a few references to the live()/delegate() method, but I'm new to jQuery so I don't fully understand how to use it. Would you mind explaining in a bit more detail (does this need to be put in the jQuery that dynamically generates the radio buttons or the jQuery that selects the radio buttons? – Stone Jan 05 '12 at 04:34
  • There's some [pretty good documentation](http://api.jquery.com/on/#direct-and-delegated-events) that deals with your problem specifically. – Ayman Safadi Jan 05 '12 at 04:38
3
$(".radio-select").live("click", function(event){           
                    event.preventDefault();
                    var $boxes = $(this).parent().parent().children();
                    $boxes.removeClass("selected");
                    $(this).parent().addClass("selected");
                    $(this).parent().find("[type=radio]").click().attr("checked","checked");
                }
            );
run
  • 1,170
  • 7
  • 14
1

The problem is that when your click method is called, the event handler that is created is only attached to all the elements that exist at that time. Your solution is either to add a call to attach the click handler when you create your element or use the on() function to attach to the selector.

Alex M
  • 3,506
  • 2
  • 20
  • 23
1

If you are using jQuery 1.3.2 and above, you need to use jQuery live. So your binding would become:

 $(".radio-select").live('click',function(event) {

            event.preventDefault();
            var $boxes = $(this).parent().parent().children();
            $boxes.removeClass("selected");
            $(this).parent().addClass("selected");
            $(this).parent().find("[type=radio]").click().attr("checked","checked");

        }
   );

If you are using jQuery below 1.3.2, use livequery plugin.

Sandeep
  • 819
  • 10
  • 16