Index: includes/ajax.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/ajax.inc,v retrieving revision 1.7 diff -u -p -r1.7 ajax.inc --- includes/ajax.inc 27 Aug 2009 04:40:12 -0000 1.7 +++ includes/ajax.inc 29 Aug 2009 16:18:52 -0000 @@ -208,9 +208,30 @@ function ajax_form_callback() { // drupal_process_form() set up. $form = drupal_rebuild_form($form_id, $form_state, $form_build_id); - // Get the callback function from the clicked button. - $ajax = $form_state['clicked_button']['#ajax']; - $callback = $ajax['callback']; + // Find the triggering element. If we can't find it, then default to + // $form_state['clicked_button'], which is only set if the triggering element + // is a button. + $triggering_element_path = !empty($_POST['ajax_triggering_element']) ? $_POST['ajax_triggering_element'] : NULL; + if (!empty($triggering_element_path)) { + $triggering_element = $form; + foreach (explode('/', $triggering_element_path) as $key) { + if (!empty($triggering_element[$key])) { + $triggering_element = $triggering_element[$key]; + } + else { + $triggering_element = NULL; + break; + } + } + } + if (empty($triggering_element)) { + $triggering_element = $form_state['clicked_button']; + } + + // Now that we have the element, get a callback if there is one. + if (!empty($triggering_element['#ajax']['callback'])) { + $callback = $triggering_element['#ajax']['callback']; + } if (function_exists($callback)) { $html = $callback($form, $form_state); @@ -305,6 +326,7 @@ function ajax_process_form($element) { 'method' => empty($element['#ajax']['method']) ? 'replace' : $element['#ajax']['method'], 'progress' => empty($element['#ajax']['progress']) ? array('type' => 'throbber') : $element['#ajax']['progress'], 'button' => isset($element['#executes_submit_callback']) ? array($element['#name'] => $element['#value']) : FALSE, + 'formPath' => implode('/', $element['#array_parents']), ); // Convert a simple #ajax['progress'] type string into an array. Index: misc/ajax.js =================================================================== RCS file: /cvs/drupal/drupal/misc/ajax.js,v retrieving revision 1.1 diff -u -p -r1.1 ajax.js --- misc/ajax.js 17 Aug 2009 07:12:15 -0000 1.1 +++ misc/ajax.js 29 Aug 2009 16:18:52 -0000 @@ -96,7 +96,7 @@ Drupal.ajax = function (base, element, e type: 'bar', message: 'Please wait...' }, - button: {}, + button: {} }; $.extend(this, defaults, element_settings); @@ -183,6 +183,10 @@ Drupal.ajax.prototype.beforeSubmit = fun // Disable the element that received the change. $(this.element).addClass('progress-disabled').attr('disabled', true); + // Server-side code needs to know what element triggered the call, so it can + // find the #ajax binding. + form_values.push({name: 'ajax_triggering_element', value: this.formPath}); + // Insert progressbar or throbber. if (this.progress.type == 'bar') { var progressBar = new Drupal.progressBar('ajax-progress-' + this.element.id, eval(this.progress.update_callback), this.progress.method, eval(this.progress.error_callback));