I think because you are setting events on <div/> , not on <select/> .
$("#opt_29821_746").live('change', function(){
it should be
$("#option_29821_746").live('change', function(){
In addition, you have a problem in that your AJAX callback resets all fields, because it just sets the HTML code returned after filling in the field, so even if the code works, it will reset every time. Consider returning a simple list (JSON will be my choice) and setting options on the client side, rather than server-side rendering. Alternatively, if you insist on using AJAX as-is, consider postponing the AJAX request until you fill in the field (fill in the field first, then the AJAX request). I assume this is a built-in onclick that makes an AJAX call. Since this is ugly, I will not be afraid to make it more ugly - you can keep onclick aside as jQuery data and put it in a line:
$('select[onchange]').each(function(i, el) { el=$(el); el.data('onchange', el.attr('onchange')); // save previous event code aside el.attr("onchange",null); // delete previous event code el.change(function() { // you can actually add more code here to invoke before regular 'onchange' event var target=$(this); if (target.data("onchange")) { (new Function(target.data("onchange"))).apply(this, arguments); } }); });
However, you will need to do this after each AJAX call when your items are replaced. You may also be able to use jQuery live() here, but it is too ugly for me to write.
Regarding the first point, I think that using the named variables would save you. For brevity, here, as I recommend you go:
(function() { // this isn't really ids but css selector; but for lack of a better name var el_id_map = { sku1: "#option_29821_746", sku2: "#option_29821_754", length: "#option_29821_753" }; var el_ids = []; var sku_id="#option_29821_798"; var sku1_map = { "3134": "TB", "3135": "LT" }, sku2_map = { "3111": "LC", "3110": "LCA" }; // map ids to array for (var key in el_id_map) { if (el_id_map.hasOwnProperty(key)) el_ids.push(el_id_map[key]); } $(el_ids.join(",")).live("change", function(){ $(sku_id).val([ sku1_map[$(el_id_map["sku1"]).val()], sku2_map[$(el_id_map["sku2"]).val()], $(el_id_map["length"]).val()].join("")); }); })()
You can put the code inside the live() handler here in the first code I did, where I posted the comment add more code here , etc. But remember, you must make sure that the code runs after each AJAX request to update the event handlers.
Again, I will just return the JSON from the server.
Change , since I already went for it, I decided to make a complete working example. Should work as is on your page, but you need to debug it :)
(function() { // you might want to generate the list using the same // server-side data that generates the elements var el_id_map = { sku1: "#option_29821_746", sku2: "#option_29821_754", // put rest of skus here length: "#option_29821_753" }; var sku_id = "#option_29821_798"; var sku1_map = { "3134": "TB", "3135": "LT" }, sku2_map = { "3111": "LC", "3110": "LCA" }; // put rest of skus here var el_ids = []; for (var key in el_id_map) { if (el_id_map.hasOwnProperty(key)) { el_ids.push(el_id_map[key]); } } function change_handler() { $(sku_id).val([ sku1_map[$(el_id_map["sku1"]).val()], sku2_map[$(el_id_map["sku2"]).val()], $(el_id_map["length"]).val()].join("")); } function hijack_changes(change_handler) { $(el_ids).each(function(i, el) { el = $(el); el.data('onchange', el.attr('onchange')); // save inline event el.attr("onchange", null); // remove inline event el.change(function() { change_handler.apply(this, arguments); var target=$(this); if (target.data("onchange")) { var handler = new Function(target.data("onchange")); handler.apply(this, arguments); } }); }); } function hijack_ajax() { var old_fn_post_process_form_files = window.fn_post_process_form_files; window.fn_post_process_form_files = function() { hijack_changes(change_handler); old_fn_post_process_form_files.apply(this, arguments); } } hijack_ajax(); hijack_changes(change_handler); })();