Jquery .change() function not working with dynamically populated SELECT list

66,881

Solution 1

Just commented on your last question...Here's what I said:

Use jQuery bind

function addSelectChange() {
   $('select').bind('change', function() {
       // yada yada
   });
} 

Call addSelectChange in your ajax success function. It should do the trick. Take a look at jQuery live event too (for when you want to set events for all current and future DOM elements in a later project or something). Unfortunately the change event and a few others aren't yet supported with live. Bind is the next best thing

Solution 2

A more up to date answer..

Since the elements are dynamically populated, you are looking for event delegation.

Don't use .live()/.bind()/.delegate(), though. You should use .on().

According to the jQuery API docs:

As of jQuery 1.7, the .on() method is the preferred method for attaching event handlers to a document. For earlier versions, the .bind() method is used for attaching an event handler directly to elements. Handlers are attached to the currently selected elements in the jQuery object, so those elements must exist at the point the call to .bind() occurs. For more flexible event binding, see the discussion of event delegation in .on().

Therefore you would use something like this:

$(document).on('change', 'select', function (e) {
    /* ... */
});

Solution 3

An example using .live()

$('#my_form_id select[name^="my_select_name"]').live('change', (function () {
    console.log( $("option:selected", this).val());
    })
 );

Solution 4

For items that are dynamically inserted into the DOM, their events must be bound with

$('.selector').bind('change',function() { doWork() });

This is because when you run $(function(){}); and bind events using $.click or $.change, etc., you are binding events to elements already existing in the DOM. Any manipulation you do after that does not get affected by whatever happens in the $(function(){}); call. $.bind tells your page to look for future elements in your selector as well as current ones.

Solution 5

try .live: http://docs.jquery.com/Events/live

From docs: Binds a handler to an event (like click) for all current - and future - matched element. Can also bind custom events.

Share:
66,881
tresstylez
Author by

tresstylez

I'm ready.

Updated on July 21, 2022

Comments

  • tresstylez
    tresstylez almost 2 years

    I have a select field that is dynamically populated with an ajax call that simply returns all the HTML select options. Here is the part of the PHP that just echo's the select tags and dynamically fills out each option/value.

    echo "<select name='player1' class='affector'>";
    echo "<option value='' selected>--".sizeof($start)." PLAYERS LOADED--</option>";
    
    foreach ($start as $value) {
        echo "<option value='".$value."'>".$value."</option>";
     }  
      echo "</select>";
    }  
    

    After this list is populated, I'm trying to call a change event, so that whenever the default option is changed in the SELECT list or in a text field with the same class, it disables a radio button set in another part of the form. (You can see the initial question I asked to get this part of the functionality working here)

    $('.affector').change(function(){
           $(this).parents('tr').find('input:radio').attr('disabled', false);
    });
    

    For some reason, even though I give the select field the proper class name (affector), when I select different options in the field, the other parts of the form do not disable. The static text field with the same class works fine. I'm stumped.

    Any ideas?

    • Skilldrick
      Skilldrick over 14 years
      Quick tip, instead of echo "<option value='".$value."'>", try: echo "<option value='$value'>". If you're accessing an array, you can do echo "<option value='{$values[0]}'>"
  • Sampson
    Sampson over 14 years
    "Currently not supported: ...change..."
  • Chance
    Chance over 14 years
    Both .change and .bind work the same way. They will only bind to elements that are currently in the DOM.
  • Ricardo Gomes
    Ricardo Gomes over 14 years
    @anurag - incorrect. if both elements are in the DOM already, yeah they work the same way. but .change will not bind new elements in the DOM (which is the reason the OP is asking the question...), .bind will bind current AND future events to elements.
  • Chance
    Chance over 14 years
    @Jason: It's not that difficult to test out.. check out this small html snippet (slexy.org/raw/s2XA8QihVm) I wrote to test if bind works for future dom elements and it doesn't. Also this is taken from jQuery's source, it basically forwards the function calls for change(), mouseover(), blur() etc.. to bind(). Here's a small snippet from jQuery's source showing that - slexy.org/view/s206rDeFeO or you can see the entire source on code.jQuery.com itself - code.jquery.com/jquery-latest.js. And live() is the function that binds to both current and future events.
  • arslaan ejaz
    arslaan ejaz over 11 years
    This .live() always works for me, at dynamically populated select field.
  • Seybsen
    Seybsen over 11 years
    .live() is deprecated now. Use something like $(document).on("change",'#my_form_id select[name^="my_select_name"]', function() { ... })
  • user889030
    user889030 over 7 years
    yes that is for all scenarios , static or dynamic content :)