From a320ae97c31eb5db75316d63dd1664492450244e Mon Sep 17 00:00:00 2001 From: Chris Oden Date: Fri, 16 Dec 2011 13:30:17 -0500 Subject: [PATCH 1/9] Issue #1373236 - Provide generic ajax manipulation for checkout page. --- shipping/uc_quote/uc_quote.module | 88 +++++++++--------------------------- uc_cart/uc_cart.api.php | 40 +++++++++++++++++ uc_cart/uc_cart.pages.inc | 82 ++++++++++++++++++++++++++++++++++ 3 files changed, 144 insertions(+), 66 deletions(-) diff --git a/shipping/uc_quote/uc_quote.module b/shipping/uc_quote/uc_quote.module index 5a5013e..4778e1c 100644 --- a/shipping/uc_quote/uc_quote.module +++ b/shipping/uc_quote/uc_quote.module @@ -240,73 +240,29 @@ function uc_quote_form_alter(&$form, &$form_state, $form_id) { } } -/** - * Implements hook_form_FORM_ID_alter() for uc_cart_checkout_form(). - * - * Adds Ajax shipping quote functionality to the checkout form. - */ -function uc_quote_form_uc_cart_checkout_form_alter(&$form, &$form_state) { - if (isset($form['panes']['delivery']['address'])) { - $form['panes']['delivery']['address']['#process'] = array('uc_store_process_address_field', 'uc_quote_process_checkout_address'); - } - if (isset($form['panes']['delivery']['select_address'])) { - $form['panes']['delivery']['select_address']['#ajax']['callback'] = 'uc_quote_select_address'; - } - // @todo: Figure out what needs to be done when copy-address box is checked. - - if (isset($form['panes']['payment']['line_items'])) { - $form['panes']['quotes']['quotes']['quote_option']['#ajax'] = array( - 'callback' => 'uc_payment_get_totals', - 'wrapper' => 'line-items-div', - ); - } -} - -/** - * Ajax callback: Updates quotes when a saved address is selected. - */ -function uc_quote_select_address($form, $form_state) { - $return = uc_quote_checkout_returned_rates($form, $form_state); - $address = uc_checkout_pane_address_render($form, $form_state); - - $return['#commands'][] = ajax_command_replace('#' . $form_state['triggering_element']['#ajax']['wrapper'], drupal_render($address)); - - return $return; -} - -/** - * Ajax callback: Updates shipping quotes when the delivery country changes. - */ -function uc_quote_country_change_wrapper(&$form, &$form_state) { - $return = uc_quote_checkout_returned_rates($form, $form_state); - $return['#commands'][] = ajax_command_replace('#uc-store-address-delivery-zone-wrapper', drupal_render(uc_store_update_address_field_zones($form, $form_state))); - return $return; -} - -/** - * Process callback: Adds Ajax functionality to delivery address fields. - */ -function uc_quote_process_checkout_address($element, $form_state) { - $ajax = array( - 'callback' => 'uc_quote_checkout_returned_rates', - 'effect' => 'slide', - 'progress' => array( - 'type' => 'throbber', - 'message' => t('Receiving shipping quotes...'), - ), - ); - - if (isset($element['delivery_postal_code'])) { - $element['delivery_postal_code']['#ajax'] = $ajax; - } - // The following replaces "uc_store_process_address_field" from uc_store - // with a wrapper that will update the available quotes when the country - // is changed. - if (isset($element['delivery_country'])) { - $element['delivery_country']['#ajax']['callback'] = 'uc_quote_country_change_wrapper'; +function uc_quote_uc_cart_checkout_ajax($child, $parent, $form_state) { + switch ($child) { + case 'delivery_country': + case 'delivery_postal_code': + case 'select_address': + return array( + 'callback' => 'uc_quote_checkout_returned_rates', + 'effect' => 'slide', + 'progress' => array( + 'type' => 'throbber', + 'message' => t('Receiving shipping quotes...'), + ), + ); + break; + case 'quote_option': + if (isset($form_state['complete form']['panes']['payment']['line_items'])) { + return array( + 'callback' => 'uc_payment_get_totals', + 'wrapper' => 'line-items-div', + ); + } + break; } - - return $element; } /** diff --git a/uc_cart/uc_cart.api.php b/uc_cart/uc_cart.api.php index ee5a374..4433152 100644 --- a/uc_cart/uc_cart.api.php +++ b/uc_cart/uc_cart.api.php @@ -422,5 +422,45 @@ function hook_uc_update_cart_item($nid, $data = array(), $qty, $cid = NULL) { } /** + * Allows modules to add ajax callbacks to checkout form elements in an orderly manner. The callbacks + * are invoked in module weight order to generate a list of ajax commands which are then returned to + * the page. Note that this hook is invoked after the $parent element has been processed - so, for example, + * a 'radios' element will already have expanded to include its radio-button children. The children, + * however, will not yet have been processed. + * + * Ajax options (such as the effect, progress message, etc.) will be determined by the heaviest module + * implementing this hook. However, the *lightest* callback to invoke theme('status_messages', ...) will + * prevent their display by heavier modules. + * + * @param $child + * The key of the element to be modified. + * @param $parent + * The element which is the parent of $child. Can be used to provide additional context. + * @param $form_state + * The current $form_state array. + * + * @return + * An array as would be provided for the '#ajax' attribute of an element. Currently, you must specify a + * 'callback' key ('path' is not supported). If the callback returns a string or renderable array, you + * must also specify a wrapper. + */ +function hook_uc_cart_checkout_ajax($child, $parent, $form_state) { + if ($child == 'delivery_country') { + return array( + 'callback' => 'uc_cart_checkout_ajax_test', + 'wrapper' => 'cart-pane', + 'effect' => 'slide', + 'progress' => array( + 'type' => 'throbber', + 'message' => t('Modifying cart contents...'), + ), + ); + } + return FALSE; +} + + + +/** * @} End of "addtogroup hooks". */ diff --git a/uc_cart/uc_cart.pages.inc b/uc_cart/uc_cart.pages.inc index 48c18cb..47ac785 100644 --- a/uc_cart/uc_cart.pages.inc +++ b/uc_cart/uc_cart.pages.inc @@ -152,6 +152,83 @@ function uc_cart_checkout() { return drupal_get_form('uc_cart_checkout_form', $order); } + +/** + * Generic ajax callback for the checkout form. + * Process a list of ajax commands attached to the specified triggering element via hook_uc_cart_checkout_ajax(). + */ +function uc_cart_checkout_ajax($form, $form_state) { + $element = $form_state['triggering_element']; + if (!empty($element['#ajax']['list'])) { + $commands = array(); + foreach ($element['#ajax']['list'] as $ajax) { + if (!empty($ajax['callback']) && function_exists($ajax['callback'])) { + $result = call_user_func($ajax['callback'], $form, $form_state); + if (!empty($result)) { + if (is_array($result) && !empty($result['#type']) && $result['#type'] == 'ajax') { + // If the callback returned an array of commands, simply add these to the list. + $commands = array_merge($commands, $result['#commands']); + } + elseif (!empty($ajax['wrapper'])) { + // Otherwise, assume the callback returned a string or render-array, and insert it into the wrapper. + $html = is_string($result) ? $result : drupal_render($result); + $commands[] = ajax_command_replace('#' . $ajax['wrapper'], $html); + $commands[] = ajax_command_prepend('#' . $ajax['wrapper'], theme('status_messages')); + } + } + } + } + } + if (!empty($commands)) { + return array('#type' => 'ajax', '#commands' => $commands); + } +} + +/** + * Process callback to add ajax to form elements. + */ +function uc_cart_checkout_form_process($form, $form_state) { + // We have to operate on the children rather than on the element itself, because the #process + // functions are called *after* form_handle_input_elements(), which is where the triggering + // element is determined. If we haven't added an '#ajax' key by that time, drupal won't be + // able to determine which callback to invoke. + foreach (element_children($form) as $child) { + $element =& $form[$child]; + + // First add this process function recursively to the children. + if (empty($element['#process']) && !empty($element['#type'])) { + // We want to be sure the default process functions for the element type are called. + $info = element_info($element['#type']); + if (!empty($info['#process'])) { + $element['#process'] = $info['#process']; + } + } + $element['#process'][] = 'uc_cart_checkout_form_process'; + + // Build a list of the ajax that modules want to add to this element. + $list = array(); + foreach (module_implements('uc_cart_checkout_ajax') as $module) { + $list[] = module_invoke($module, 'uc_cart_checkout_ajax', $child, $form, $form_state); + } + $list = array_filter($list); + if (!empty($list)) { + if (!empty($element['#ajax'])) { + array_unshift($list, $element['#ajax']); + } + $element['#ajax'] = array(); + foreach ($list as $ajax) { + $element['#ajax'] = $ajax + $element['#ajax']; + } + $element['#ajax'] = array( + 'callback' => 'uc_cart_checkout_ajax', + 'list' => $list + ) + $element['#ajax']; + } + } + + return $form; +} + /** * The checkout form built up from the enabled checkout panes. * @@ -278,9 +355,14 @@ function uc_cart_checkout_form($form, &$form_state, $order) { '#type' => 'submit', '#value' => t('Review order'), ); + $form['#process'] = array('uc_cart_checkout_form_process'); +<<<<<<< HEAD unset($_SESSION['uc_checkout'][$order->order_id]); +======= + unset($_SESSION['do_review']); +>>>>>>> Issue #1373236 - Provide generic ajax manipulation for checkout page. return $form; } -- 1.7.4.1 From 93c44e984a4540cd43c4466e684e562305f79186 Mon Sep 17 00:00:00 2001 From: Dave Long Date: Sat, 17 Dec 2011 17:44:42 +0000 Subject: [PATCH 2/9] Reorganise code and add/reformat comments. --- shipping/uc_quote/uc_quote.module | 3 + uc_cart/uc_cart.pages.inc | 166 +++++++++++++++++++------------------ 2 files changed, 87 insertions(+), 82 deletions(-) diff --git a/shipping/uc_quote/uc_quote.module b/shipping/uc_quote/uc_quote.module index 4778e1c..f4efce4 100644 --- a/shipping/uc_quote/uc_quote.module +++ b/shipping/uc_quote/uc_quote.module @@ -240,6 +240,9 @@ function uc_quote_form_alter(&$form, &$form_state, $form_id) { } } +/** + * Implements hook_uc_cart_checkout_ajax(). + */ function uc_quote_uc_cart_checkout_ajax($child, $parent, $form_state) { switch ($child) { case 'delivery_country': diff --git a/uc_cart/uc_cart.pages.inc b/uc_cart/uc_cart.pages.inc index 47ac785..38dc0f8 100644 --- a/uc_cart/uc_cart.pages.inc +++ b/uc_cart/uc_cart.pages.inc @@ -152,91 +152,15 @@ function uc_cart_checkout() { return drupal_get_form('uc_cart_checkout_form', $order); } - -/** - * Generic ajax callback for the checkout form. - * Process a list of ajax commands attached to the specified triggering element via hook_uc_cart_checkout_ajax(). - */ -function uc_cart_checkout_ajax($form, $form_state) { - $element = $form_state['triggering_element']; - if (!empty($element['#ajax']['list'])) { - $commands = array(); - foreach ($element['#ajax']['list'] as $ajax) { - if (!empty($ajax['callback']) && function_exists($ajax['callback'])) { - $result = call_user_func($ajax['callback'], $form, $form_state); - if (!empty($result)) { - if (is_array($result) && !empty($result['#type']) && $result['#type'] == 'ajax') { - // If the callback returned an array of commands, simply add these to the list. - $commands = array_merge($commands, $result['#commands']); - } - elseif (!empty($ajax['wrapper'])) { - // Otherwise, assume the callback returned a string or render-array, and insert it into the wrapper. - $html = is_string($result) ? $result : drupal_render($result); - $commands[] = ajax_command_replace('#' . $ajax['wrapper'], $html); - $commands[] = ajax_command_prepend('#' . $ajax['wrapper'], theme('status_messages')); - } - } - } - } - } - if (!empty($commands)) { - return array('#type' => 'ajax', '#commands' => $commands); - } -} - -/** - * Process callback to add ajax to form elements. - */ -function uc_cart_checkout_form_process($form, $form_state) { - // We have to operate on the children rather than on the element itself, because the #process - // functions are called *after* form_handle_input_elements(), which is where the triggering - // element is determined. If we haven't added an '#ajax' key by that time, drupal won't be - // able to determine which callback to invoke. - foreach (element_children($form) as $child) { - $element =& $form[$child]; - - // First add this process function recursively to the children. - if (empty($element['#process']) && !empty($element['#type'])) { - // We want to be sure the default process functions for the element type are called. - $info = element_info($element['#type']); - if (!empty($info['#process'])) { - $element['#process'] = $info['#process']; - } - } - $element['#process'][] = 'uc_cart_checkout_form_process'; - - // Build a list of the ajax that modules want to add to this element. - $list = array(); - foreach (module_implements('uc_cart_checkout_ajax') as $module) { - $list[] = module_invoke($module, 'uc_cart_checkout_ajax', $child, $form, $form_state); - } - $list = array_filter($list); - if (!empty($list)) { - if (!empty($element['#ajax'])) { - array_unshift($list, $element['#ajax']); - } - $element['#ajax'] = array(); - foreach ($list as $ajax) { - $element['#ajax'] = $ajax + $element['#ajax']; - } - $element['#ajax'] = array( - 'callback' => 'uc_cart_checkout_ajax', - 'list' => $list - ) + $element['#ajax']; - } - } - - return $form; -} - /** * The checkout form built up from the enabled checkout panes. * * @param $order * The order that is being checked out. * + * @see uc_cart_checkout_form_process() * @see uc_cart_checkout_form_validate() - * @see uc_cart_checkout_form_review() + * @see uc_cart_checkout_form_submit() * @see uc_cart_checkout_review() * @see theme_uc_cart_checkout_form() * @ingroup forms @@ -357,12 +281,8 @@ function uc_cart_checkout_form($form, &$form_state, $order) { ); $form['#process'] = array('uc_cart_checkout_form_process'); -<<<<<<< HEAD unset($_SESSION['uc_checkout'][$order->order_id]); -======= - unset($_SESSION['do_review']); ->>>>>>> Issue #1373236 - Provide generic ajax manipulation for checkout page. return $form; } @@ -447,6 +367,88 @@ function uc_cart_checkout_form_cancel($form, &$form_state) { } /** + * Form process callback to add Ajax to form elements. + * + * @see uc_cart_checkout_form() + * @see uc_cart_checkout_ajax() + */ +function uc_cart_checkout_form_process($form, $form_state) { + // We have to operate on the children rather than on the element itself, as + // #process functions are called *after* form_handle_input_elements(), + // which is where the triggering element is determined. If we haven't added + // an '#ajax' key by that time, Drupal won't be able to determine which + // callback to invoke. + foreach (element_children($form) as $child) { + $element =& $form[$child]; + + // First add this process function recursively to the children. + if (empty($element['#process']) && !empty($element['#type'])) { + // We want to be sure the default process functions for the element type are called. + $info = element_info($element['#type']); + if (!empty($info['#process'])) { + $element['#process'] = $info['#process']; + } + } + $element['#process'][] = 'uc_cart_checkout_form_process'; + + // Build a list of the ajax that modules want to add to this element. + $list = array(); + foreach (module_implements('uc_cart_checkout_ajax') as $module) { + $list[] = module_invoke($module, 'uc_cart_checkout_ajax', $child, $form, $form_state); + } + $list = array_filter($list); + if (!empty($list)) { + if (!empty($element['#ajax'])) { + array_unshift($list, $element['#ajax']); + } + $element['#ajax'] = array(); + foreach ($list as $ajax) { + $element['#ajax'] = $ajax + $element['#ajax']; + } + $element['#ajax'] = array( + 'callback' => 'uc_cart_checkout_ajax', + 'list' => $list + ) + $element['#ajax']; + } + } + + return $form; +} + +/** + * Ajax callback multiplexer for the checkout form. + * + * Processes a list of Ajax commands attached to the triggering element + * via hook_uc_cart_checkout_ajax(). + */ +function uc_cart_checkout_ajax($form, $form_state) { + $element = $form_state['triggering_element']; + if (!empty($element['#ajax']['list'])) { + $commands = array(); + foreach ($element['#ajax']['list'] as $ajax) { + if (!empty($ajax['callback']) && function_exists($ajax['callback'])) { + $result = call_user_func($ajax['callback'], $form, $form_state); + if (!empty($result)) { + if (is_array($result) && !empty($result['#type']) && $result['#type'] == 'ajax') { + // If the callback returned an array of commands, simply add these to the list. + $commands = array_merge($commands, $result['#commands']); + } + elseif (!empty($ajax['wrapper'])) { + // Otherwise, assume the callback returned a string or render-array, and insert it into the wrapper. + $html = is_string($result) ? $result : drupal_render($result); + $commands[] = ajax_command_replace('#' . $ajax['wrapper'], $html); + $commands[] = ajax_command_prepend('#' . $ajax['wrapper'], theme('status_messages')); + } + } + } + } + } + if (!empty($commands)) { + return array('#type' => 'ajax', '#commands' => $commands); + } +} + +/** * Allows a customer to review their order before finally submitting it. * * @see uc_cart_checkout_form() -- 1.7.4.1 From 2d9bf6163f6068e545b05ffa5af82a35b32ce4e0 Mon Sep 17 00:00:00 2001 From: Dave Long Date: Sat, 17 Dec 2011 23:19:42 +0000 Subject: [PATCH 3/9] Issue #1373236: Simplify hook_uc_cart_checkout_ajax() and ensure it is only called once. --- payment/uc_payment/uc_payment.module | 4 ++- shipping/uc_quote/uc_quote.module | 33 +++++++------------- uc_cart/uc_cart.pages.inc | 55 ++++++++++++++++----------------- 3 files changed, 41 insertions(+), 51 deletions(-) diff --git a/payment/uc_payment/uc_payment.module b/payment/uc_payment/uc_payment.module index 4e7df73..848cc60 100644 --- a/payment/uc_payment/uc_payment.module +++ b/payment/uc_payment/uc_payment.module @@ -252,7 +252,9 @@ function uc_payment_uc_order_state() { * The formatted HTML of the order total preview if $return is set to TRUE. */ function uc_payment_get_totals($form, $form_state) { - return $form['panes']['payment']['line_items']; + $commands[] = ajax_command_replace('#line-items-div', drupal_render($form['panes']['payment']['line_items'])); + + return array('#type' => 'ajax', '#commands' => $commands); } /** diff --git a/shipping/uc_quote/uc_quote.module b/shipping/uc_quote/uc_quote.module index f4efce4..9005176 100644 --- a/shipping/uc_quote/uc_quote.module +++ b/shipping/uc_quote/uc_quote.module @@ -243,29 +243,18 @@ function uc_quote_form_alter(&$form, &$form_state, $form_id) { /** * Implements hook_uc_cart_checkout_ajax(). */ -function uc_quote_uc_cart_checkout_ajax($child, $parent, $form_state) { - switch ($child) { - case 'delivery_country': - case 'delivery_postal_code': - case 'select_address': - return array( - 'callback' => 'uc_quote_checkout_returned_rates', - 'effect' => 'slide', - 'progress' => array( - 'type' => 'throbber', - 'message' => t('Receiving shipping quotes...'), - ), - ); - break; - case 'quote_option': - if (isset($form_state['complete form']['panes']['payment']['line_items'])) { - return array( - 'callback' => 'uc_payment_get_totals', - 'wrapper' => 'line-items-div', - ); - } - break; +function uc_quote_uc_cart_checkout_ajax($form, $form_state) { + $fields = array( + 'delivery_country' => 'uc_quote_checkout_returned_rates', + 'delivery_postal_code' => 'uc_quote_checkout_returned_rates', + 'select_address' => 'uc_quote_checkout_returned_rates', + ); + + if (isset($form['panes']['payment']['line_items'])) { + $fields['quote_option'] = 'uc_payment_get_totals'; } + + return $fields; } /** diff --git a/uc_cart/uc_cart.pages.inc b/uc_cart/uc_cart.pages.inc index 38dc0f8..ca89f67 100644 --- a/uc_cart/uc_cart.pages.inc +++ b/uc_cart/uc_cart.pages.inc @@ -373,6 +373,12 @@ function uc_cart_checkout_form_cancel($form, &$form_state) { * @see uc_cart_checkout_ajax() */ function uc_cart_checkout_form_process($form, $form_state) { + static $fields; + + if (!isset($fields)) { + $fields = module_invoke_all('uc_cart_checkout_ajax', $form, $form_state); + } + // We have to operate on the children rather than on the element itself, as // #process functions are called *after* form_handle_input_elements(), // which is where the triggering element is determined. If we haven't added @@ -391,24 +397,20 @@ function uc_cart_checkout_form_process($form, $form_state) { } $element['#process'][] = 'uc_cart_checkout_form_process'; - // Build a list of the ajax that modules want to add to this element. - $list = array(); - foreach (module_implements('uc_cart_checkout_ajax') as $module) { - $list[] = module_invoke($module, 'uc_cart_checkout_ajax', $child, $form, $form_state); - } - $list = array_filter($list); - if (!empty($list)) { + if (isset($fields[$child])) { + $list = is_array($fields[$child]) ? $fields[$child] : array($fields[$child]); + if (!empty($element['#ajax'])) { - array_unshift($list, $element['#ajax']); + array_unshift($list, $element['#ajax']['callback']); } - $element['#ajax'] = array(); - foreach ($list as $ajax) { - $element['#ajax'] = $ajax + $element['#ajax']; + else { + $element['#ajax'] = array(); } - $element['#ajax'] = array( + + $element['#ajax'] = array_merge($element['#ajax'], array( 'callback' => 'uc_cart_checkout_ajax', - 'list' => $list - ) + $element['#ajax']; + 'list' => $list, + )); } } @@ -425,20 +427,17 @@ function uc_cart_checkout_ajax($form, $form_state) { $element = $form_state['triggering_element']; if (!empty($element['#ajax']['list'])) { $commands = array(); - foreach ($element['#ajax']['list'] as $ajax) { - if (!empty($ajax['callback']) && function_exists($ajax['callback'])) { - $result = call_user_func($ajax['callback'], $form, $form_state); - if (!empty($result)) { - if (is_array($result) && !empty($result['#type']) && $result['#type'] == 'ajax') { - // If the callback returned an array of commands, simply add these to the list. - $commands = array_merge($commands, $result['#commands']); - } - elseif (!empty($ajax['wrapper'])) { - // Otherwise, assume the callback returned a string or render-array, and insert it into the wrapper. - $html = is_string($result) ? $result : drupal_render($result); - $commands[] = ajax_command_replace('#' . $ajax['wrapper'], $html); - $commands[] = ajax_command_prepend('#' . $ajax['wrapper'], theme('status_messages')); - } + foreach ($element['#ajax']['list'] as $callback) { + if (!empty($callback) && function_exists($callback) && $result = $callback($form, $form_state)) { + if (is_array($result) && !empty($result['#type']) && $result['#type'] == 'ajax') { + // If the callback returned an array of commands, simply add these to the list. + $commands = array_merge($commands, $result['#commands']); + } + elseif (!empty($element['#ajax']['wrapper'])) { + // Otherwise, assume the callback returned a string or render-array, and insert it into the wrapper. + $html = is_string($result) ? $result : drupal_render($result); + $commands[] = ajax_command_replace('#' . $element['#ajax']['wrapper'], $html); + $commands[] = ajax_command_prepend('#' . $element['#ajax']['wrapper'], theme('status_messages')); } } } -- 1.7.4.1 From a15d9bbc336bdc3afa8de31c71eebd7f0c625545 Mon Sep 17 00:00:00 2001 From: Dave Long Date: Sat, 17 Dec 2011 19:07:52 +0000 Subject: [PATCH 4/9] Issue #1373236: Allow country selection to limit and update payment methods at checkout. --- payment/uc_payment/uc_payment_checkout_pane.inc | 40 ++++++++++++++++------ 1 files changed, 29 insertions(+), 11 deletions(-) diff --git a/payment/uc_payment/uc_payment_checkout_pane.inc b/payment/uc_payment/uc_payment_checkout_pane.inc index 755203c..95a6592 100644 --- a/payment/uc_payment/uc_payment_checkout_pane.inc +++ b/payment/uc_payment/uc_payment_checkout_pane.inc @@ -25,8 +25,6 @@ function uc_checkout_pane_payment($op, &$order, $form = NULL, &$form_state = NUL $methods = _uc_payment_method_list(); $options = array(); - $default = NULL; - foreach ($methods as $id => $method) { $set = rules_config_load('uc_payment_method_' . $method['id']); if ($set && !$set->execute($order)) { @@ -43,15 +41,12 @@ function uc_checkout_pane_payment($op, &$order, $form = NULL, &$form_state = NUL drupal_goto('cart'); } - if (count($options)) { - if (isset($form_state['values']) && - isset($form_state['values']['panes']['payment']['payment_method']) && - in_array($form_state['values']['panes']['payment']['payment_method'], array_keys($options))) { - $default = $form_state['values']['panes']['payment']['payment_method']; - } - else { - $default = (count($options) == 1 || empty($order->payment_method)) ? key($options) : $order->payment_method; - } + $default = $order->payment_method; + if (isset($form_state['values']['panes']['payment']['payment_method'])) { + $default = $form_state['values']['panes']['payment']['payment_method']; + } + if (!isset($options[$default])) { + $default = key($options); } if (count($options) > 1) { @@ -76,6 +71,8 @@ function uc_checkout_pane_payment($op, &$order, $form = NULL, &$form_state = NUL 'type' => 'throbber', ), ), + '#prefix' => '
', + '#suffix' => '
', ); $contents['details'] = array( @@ -143,3 +140,24 @@ function uc_checkout_pane_payment($op, &$order, $form = NULL, &$form_state = NUL function uc_payment_checkout_payment_details($form, $form_state) { return $form['panes']['payment']['details']; } + +/** + * Implements hook_uc_cart_checkout_ajax(). + */ +function uc_payment_uc_cart_checkout_ajax($form, $form_state) { + return array( + 'billing_country' => 'uc_payment_checkout_payment_methods', + 'delivery_country' => 'uc_payment_checkout_payment_methods', + ); +} + +/** + * AJAX callback for updating the list of payment methods. + */ +function uc_payment_checkout_payment_methods($form, $form_state) { + $commands[] = ajax_command_replace('#payment-method', drupal_render($form['panes']['payment']['payment_method'])); + $commands[] = ajax_command_replace('#payment-details', drupal_render($form['panes']['payment']['details'])); + $commands[] = ajax_command_prepend('#payment-method', theme('status_messages')); + + return array('#type' => 'ajax', '#commands' => $commands); +} -- 1.7.4.1 From 3b41a8404ffa16f85e6e890e49dc2af6d76cbadc Mon Sep 17 00:00:00 2001 From: Chris Oden Date: Sun, 18 Dec 2011 21:37:20 -0500 Subject: [PATCH 5/9] Issue #1373236: Abstract ajax attach functionality so it is available on all forms. --- payment/uc_payment/uc_payment_checkout_pane.inc | 14 ++-- shipping/uc_quote/uc_quote.module | 24 ++++--- uc_cart/uc_cart.api.php | 40 ----------- uc_cart/uc_cart.pages.inc | 83 +---------------------- uc_store/includes/uc_ajax_attach.inc | 79 +++++++++++++++++++++ uc_store/uc_store.api.php | 21 ++++++ uc_store/uc_store.module | 1 + 7 files changed, 123 insertions(+), 139 deletions(-) create mode 100644 uc_store/includes/uc_ajax_attach.inc diff --git a/payment/uc_payment/uc_payment_checkout_pane.inc b/payment/uc_payment/uc_payment_checkout_pane.inc index 95a6592..b12775a 100644 --- a/payment/uc_payment/uc_payment_checkout_pane.inc +++ b/payment/uc_payment/uc_payment_checkout_pane.inc @@ -142,13 +142,15 @@ function uc_payment_checkout_payment_details($form, $form_state) { } /** - * Implements hook_uc_cart_checkout_ajax(). + * Implements hook_uc_ajax_attach(). */ -function uc_payment_uc_cart_checkout_ajax($form, $form_state) { - return array( - 'billing_country' => 'uc_payment_checkout_payment_methods', - 'delivery_country' => 'uc_payment_checkout_payment_methods', - ); +function uc_payment_uc_ajax_attach($form, $form_state) { + if ($form['#form_id'] == 'uc_cart_checkout_form') { + return array( + 'billing_country' => 'uc_payment_checkout_payment_methods', + 'delivery_country' => 'uc_payment_checkout_payment_methods', + ); + } } /** diff --git a/shipping/uc_quote/uc_quote.module b/shipping/uc_quote/uc_quote.module index 9005176..714c1ea 100644 --- a/shipping/uc_quote/uc_quote.module +++ b/shipping/uc_quote/uc_quote.module @@ -241,20 +241,22 @@ function uc_quote_form_alter(&$form, &$form_state, $form_id) { } /** - * Implements hook_uc_cart_checkout_ajax(). + * Implements hook_uc_ajax_attach(). */ -function uc_quote_uc_cart_checkout_ajax($form, $form_state) { - $fields = array( - 'delivery_country' => 'uc_quote_checkout_returned_rates', - 'delivery_postal_code' => 'uc_quote_checkout_returned_rates', - 'select_address' => 'uc_quote_checkout_returned_rates', - ); +function uc_quote_uc_ajax_attach($form, $form_state) { + if ($form['#form_id'] == 'uc_cart_checkout_form') { + $fields = array( + 'delivery_country' => 'uc_quote_checkout_returned_rates', + 'delivery_postal_code' => 'uc_quote_checkout_returned_rates', + 'select_address' => 'uc_quote_checkout_returned_rates', + ); - if (isset($form['panes']['payment']['line_items'])) { - $fields['quote_option'] = 'uc_payment_get_totals'; - } + if (isset($form['panes']['payment']['line_items'])) { + $fields['quote_option'] = 'uc_payment_get_totals'; + } - return $fields; + return $fields; + } } /** diff --git a/uc_cart/uc_cart.api.php b/uc_cart/uc_cart.api.php index 4433152..ee5a374 100644 --- a/uc_cart/uc_cart.api.php +++ b/uc_cart/uc_cart.api.php @@ -422,45 +422,5 @@ function hook_uc_update_cart_item($nid, $data = array(), $qty, $cid = NULL) { } /** - * Allows modules to add ajax callbacks to checkout form elements in an orderly manner. The callbacks - * are invoked in module weight order to generate a list of ajax commands which are then returned to - * the page. Note that this hook is invoked after the $parent element has been processed - so, for example, - * a 'radios' element will already have expanded to include its radio-button children. The children, - * however, will not yet have been processed. - * - * Ajax options (such as the effect, progress message, etc.) will be determined by the heaviest module - * implementing this hook. However, the *lightest* callback to invoke theme('status_messages', ...) will - * prevent their display by heavier modules. - * - * @param $child - * The key of the element to be modified. - * @param $parent - * The element which is the parent of $child. Can be used to provide additional context. - * @param $form_state - * The current $form_state array. - * - * @return - * An array as would be provided for the '#ajax' attribute of an element. Currently, you must specify a - * 'callback' key ('path' is not supported). If the callback returns a string or renderable array, you - * must also specify a wrapper. - */ -function hook_uc_cart_checkout_ajax($child, $parent, $form_state) { - if ($child == 'delivery_country') { - return array( - 'callback' => 'uc_cart_checkout_ajax_test', - 'wrapper' => 'cart-pane', - 'effect' => 'slide', - 'progress' => array( - 'type' => 'throbber', - 'message' => t('Modifying cart contents...'), - ), - ); - } - return FALSE; -} - - - -/** * @} End of "addtogroup hooks". */ diff --git a/uc_cart/uc_cart.pages.inc b/uc_cart/uc_cart.pages.inc index ca89f67..262696c 100644 --- a/uc_cart/uc_cart.pages.inc +++ b/uc_cart/uc_cart.pages.inc @@ -279,7 +279,7 @@ function uc_cart_checkout_form($form, &$form_state, $order) { '#type' => 'submit', '#value' => t('Review order'), ); - $form['#process'] = array('uc_cart_checkout_form_process'); + $form['#process'] = array('uc_ajax_attach_process_form'); unset($_SESSION['uc_checkout'][$order->order_id]); @@ -367,87 +367,6 @@ function uc_cart_checkout_form_cancel($form, &$form_state) { } /** - * Form process callback to add Ajax to form elements. - * - * @see uc_cart_checkout_form() - * @see uc_cart_checkout_ajax() - */ -function uc_cart_checkout_form_process($form, $form_state) { - static $fields; - - if (!isset($fields)) { - $fields = module_invoke_all('uc_cart_checkout_ajax', $form, $form_state); - } - - // We have to operate on the children rather than on the element itself, as - // #process functions are called *after* form_handle_input_elements(), - // which is where the triggering element is determined. If we haven't added - // an '#ajax' key by that time, Drupal won't be able to determine which - // callback to invoke. - foreach (element_children($form) as $child) { - $element =& $form[$child]; - - // First add this process function recursively to the children. - if (empty($element['#process']) && !empty($element['#type'])) { - // We want to be sure the default process functions for the element type are called. - $info = element_info($element['#type']); - if (!empty($info['#process'])) { - $element['#process'] = $info['#process']; - } - } - $element['#process'][] = 'uc_cart_checkout_form_process'; - - if (isset($fields[$child])) { - $list = is_array($fields[$child]) ? $fields[$child] : array($fields[$child]); - - if (!empty($element['#ajax'])) { - array_unshift($list, $element['#ajax']['callback']); - } - else { - $element['#ajax'] = array(); - } - - $element['#ajax'] = array_merge($element['#ajax'], array( - 'callback' => 'uc_cart_checkout_ajax', - 'list' => $list, - )); - } - } - - return $form; -} - -/** - * Ajax callback multiplexer for the checkout form. - * - * Processes a list of Ajax commands attached to the triggering element - * via hook_uc_cart_checkout_ajax(). - */ -function uc_cart_checkout_ajax($form, $form_state) { - $element = $form_state['triggering_element']; - if (!empty($element['#ajax']['list'])) { - $commands = array(); - foreach ($element['#ajax']['list'] as $callback) { - if (!empty($callback) && function_exists($callback) && $result = $callback($form, $form_state)) { - if (is_array($result) && !empty($result['#type']) && $result['#type'] == 'ajax') { - // If the callback returned an array of commands, simply add these to the list. - $commands = array_merge($commands, $result['#commands']); - } - elseif (!empty($element['#ajax']['wrapper'])) { - // Otherwise, assume the callback returned a string or render-array, and insert it into the wrapper. - $html = is_string($result) ? $result : drupal_render($result); - $commands[] = ajax_command_replace('#' . $element['#ajax']['wrapper'], $html); - $commands[] = ajax_command_prepend('#' . $element['#ajax']['wrapper'], theme('status_messages')); - } - } - } - } - if (!empty($commands)) { - return array('#type' => 'ajax', '#commands' => $commands); - } -} - -/** * Allows a customer to review their order before finally submitting it. * * @see uc_cart_checkout_form() diff --git a/uc_store/includes/uc_ajax_attach.inc b/uc_store/includes/uc_ajax_attach.inc new file mode 100644 index 0000000..8d98247 --- /dev/null +++ b/uc_store/includes/uc_ajax_attach.inc @@ -0,0 +1,79 @@ + 'uc_ajax_attach_multiplex', + 'list' => $list, + )); + //dpm($element); + } + } + + return $form; +} + +/** + * Ajax callback multiplexer. + * + * Processes a list of Ajax commands attached to the triggering element + * via hook_uc_ajax_attach(). + */ +function uc_ajax_attach_multiplex($form, $form_state) { + $element = $form_state['triggering_element']; + if (!empty($element['#ajax']['list'])) { + $commands = array(); + foreach ($element['#ajax']['list'] as $callback) { + if (!empty($callback) && function_exists($callback) && $result = $callback($form, $form_state)) { + if (is_array($result) && !empty($result['#type']) && $result['#type'] == 'ajax') { + // If the callback returned an array of commands, simply add these to the list. + $commands = array_merge($commands, $result['#commands']); + } + elseif (!empty($element['#ajax']['wrapper'])) { + // Otherwise, assume the callback returned a string or render-array, and insert it into the wrapper. + $html = is_string($result) ? $result : drupal_render($result); + $commands[] = ajax_command_replace('#' . $element['#ajax']['wrapper'], $html); + $commands[] = ajax_command_prepend('#' . $element['#ajax']['wrapper'], theme('status_messages')); + } + } + } + } + if (!empty($commands)) { + return array('#type' => 'ajax', '#commands' => $commands); + } +} + diff --git a/uc_store/uc_store.api.php b/uc_store/uc_store.api.php index 8689326..3d67765 100644 --- a/uc_store/uc_store.api.php +++ b/uc_store/uc_store.api.php @@ -11,6 +11,27 @@ */ /** + * Allows modules to add ajax callbacks to form elements in an orderly manner. The callbacks + * are invoked in module weight order to generate a list of ajax commands which are then returned to + * the page. Note that this hook is invoked before the form has been completely processed, so children + * of elements which are expanded (like 'radios') will not yet be present in the form. However, if you + * know the names of these elements, you may still specify ajax callbacks to be attached to them. + * + * @param $form + * The form to which ajax is being attached. + * @param $form_state + * The $form_state array. + * + * @return + * An array of ajax callbacks, keyed by the name of the element to which each should be attached. + */ +function hook_uc_ajax_attach($form, $form_state) { + if ($form['#form_id'] == 'uc_cart_checkout_form') { + return array('delivery_country' => 'mymodule_delivery_country_ajax'); + } +} + +/** * Allows modules to alter the TAPIr table after the rows are populated. * * The example below adds a value for the custom 'designer' column to the table diff --git a/uc_store/uc_store.module b/uc_store/uc_store.module index cada91c..9bb3ef7 100644 --- a/uc_store/uc_store.module +++ b/uc_store/uc_store.module @@ -224,6 +224,7 @@ function uc_store_admin_access() { */ function uc_store_init() { module_load_include('inc', 'uc_store', 'includes/tapir'); + module_load_include('inc', 'uc_store', 'includes/uc_ajax_attach'); global $conf; $conf['i18n_variables'][] = 'uc_store_name'; -- 1.7.4.1 From 674154df91d1718ee1f11ff3925f33d9616b364b Mon Sep 17 00:00:00 2001 From: Chris Oden Date: Sun, 18 Dec 2011 21:49:16 -0500 Subject: [PATCH 6/9] Issue #1373236: Require ajax attach callbacks to provide the parents of the element to which they want to attach ajax. --- payment/uc_payment/uc_payment_checkout_pane.inc | 8 ++++---- shipping/uc_quote/uc_quote.module | 12 +++++------- uc_store/includes/uc_ajax_attach.inc | 7 ++++--- uc_store/uc_store.api.php | 7 +++++-- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/payment/uc_payment/uc_payment_checkout_pane.inc b/payment/uc_payment/uc_payment_checkout_pane.inc index b12775a..a879483 100644 --- a/payment/uc_payment/uc_payment_checkout_pane.inc +++ b/payment/uc_payment/uc_payment_checkout_pane.inc @@ -146,10 +146,10 @@ function uc_payment_checkout_payment_details($form, $form_state) { */ function uc_payment_uc_ajax_attach($form, $form_state) { if ($form['#form_id'] == 'uc_cart_checkout_form') { - return array( - 'billing_country' => 'uc_payment_checkout_payment_methods', - 'delivery_country' => 'uc_payment_checkout_payment_methods', - ); + $fields = array(); + $fields['panes']['billing']['address']['billing_country'] = 'uc_payment_checkout_payment_methods'; + $fields['panes']['delivery']['address']['delivery_country'] = 'uc_payment_checkout_payment_methods'; + return $fields; } } diff --git a/shipping/uc_quote/uc_quote.module b/shipping/uc_quote/uc_quote.module index 714c1ea..92898ed 100644 --- a/shipping/uc_quote/uc_quote.module +++ b/shipping/uc_quote/uc_quote.module @@ -245,16 +245,14 @@ function uc_quote_form_alter(&$form, &$form_state, $form_id) { */ function uc_quote_uc_ajax_attach($form, $form_state) { if ($form['#form_id'] == 'uc_cart_checkout_form') { - $fields = array( - 'delivery_country' => 'uc_quote_checkout_returned_rates', - 'delivery_postal_code' => 'uc_quote_checkout_returned_rates', - 'select_address' => 'uc_quote_checkout_returned_rates', - ); + $fields = array(); + $fields['panes']['delivery']['address']['delivery_country'] = 'uc_quote_checkout_returned_rates'; + $fields['panes']['delivery']['address']['delivery_postal_code'] = 'uc_quote_checkout_returned_rates'; + $fields['panes']['delivery']['select_address'] = 'uc_quote_checkout_returned_rates'; if (isset($form['panes']['payment']['line_items'])) { - $fields['quote_option'] = 'uc_payment_get_totals'; + $fields['panes']['quotes']['quotes']['quote_option'] = 'uc_payment_get_totals'; } - return $fields; } } diff --git a/uc_store/includes/uc_ajax_attach.inc b/uc_store/includes/uc_ajax_attach.inc index 8d98247..eb3ce14 100644 --- a/uc_store/includes/uc_ajax_attach.inc +++ b/uc_store/includes/uc_ajax_attach.inc @@ -25,9 +25,10 @@ function uc_ajax_attach_process_form($form, &$form_state) { } } $element['#process'][] = 'uc_ajax_attach_process_form'; - - if (isset($fields[$child])) { - $list = is_array($fields[$child]) ? $fields[$child] : array($fields[$child]); + $parents = $form['#array_parents']; + array_push($parents, $child); + if ($list = drupal_array_get_nested_value($fields, $parents)) { + $list = is_array($list) ? $list : array($list); if (!empty($element['#ajax'])) { array_unshift($list, $element['#ajax']['callback']); diff --git a/uc_store/uc_store.api.php b/uc_store/uc_store.api.php index 3d67765..f43f9a5 100644 --- a/uc_store/uc_store.api.php +++ b/uc_store/uc_store.api.php @@ -23,11 +23,14 @@ * The $form_state array. * * @return - * An array of ajax callbacks, keyed by the name of the element to which each should be attached. + * An nested array of ajax callbacks. The keys of this array must match the parent keys of the element to which + * ajax is being attached. */ function hook_uc_ajax_attach($form, $form_state) { if ($form['#form_id'] == 'uc_cart_checkout_form') { - return array('delivery_country' => 'mymodule_delivery_country_ajax'); + $fields = array(); + $fields['panes']['delivery']['address']['delivery_country'] = 'mymodule_delivery_country_ajax'; + return $fields; } } -- 1.7.4.1 From 6b779c8380fe098d2dc8451563da59c4d0510c30 Mon Sep 17 00:00:00 2001 From: Chris Oden Date: Mon, 19 Dec 2011 11:58:24 -0500 Subject: [PATCH 7/9] Issue #1373236: Allow country change on order edit form to update available shipping quotes. --- shipping/uc_quote/uc_quote.module | 5 +++++ uc_order/uc_order.admin.inc | 2 +- 2 files changed, 6 insertions(+), 1 deletions(-) diff --git a/shipping/uc_quote/uc_quote.module b/shipping/uc_quote/uc_quote.module index 92898ed..9b2f407 100644 --- a/shipping/uc_quote/uc_quote.module +++ b/shipping/uc_quote/uc_quote.module @@ -255,6 +255,11 @@ function uc_quote_uc_ajax_attach($form, $form_state) { } return $fields; } + elseif ($form['#form_id'] == 'uc_order_edit_form') { + $fields = array(); + $fields['ship_to']['delivery_country'] = 'uc_quote_order_returned_rates'; + return $fields; + } } /** diff --git a/uc_order/uc_order.admin.inc b/uc_order/uc_order.admin.inc index 80865e1..ef7b1fa 100644 --- a/uc_order/uc_order.admin.inc +++ b/uc_order/uc_order.admin.inc @@ -1057,7 +1057,7 @@ function uc_order_edit_form($form, &$form_state, $order) { } field_attach_form('uc_order', $order, $form, $form_state); - + $form['#process'] = array('uc_ajax_attach_process_form'); return $form; } -- 1.7.4.1 From 61d1b21e90e8f0eafa4b7d4ca138676522400158 Mon Sep 17 00:00:00 2001 From: Dave Long Date: Wed, 11 Apr 2012 22:45:03 +0100 Subject: [PATCH 8/9] Replace hook_uc_ajax_attach() with form state storage. --- payment/uc_payment/uc_payment_checkout_pane.inc | 15 ++------- shipping/uc_quote/uc_quote.module | 29 ++++------------- uc_cart/uc_cart.pages.inc | 2 +- uc_order/uc_order.admin.inc | 2 +- uc_store/includes/uc_ajax_attach.inc | 38 ++++++++++++----------- uc_store/uc_store.api.php | 24 -------------- 6 files changed, 32 insertions(+), 78 deletions(-) diff --git a/payment/uc_payment/uc_payment_checkout_pane.inc b/payment/uc_payment/uc_payment_checkout_pane.inc index a879483..091cd87 100644 --- a/payment/uc_payment/uc_payment_checkout_pane.inc +++ b/payment/uc_payment/uc_payment_checkout_pane.inc @@ -92,6 +92,9 @@ function uc_checkout_pane_payment($op, &$order, $form = NULL, &$form_state = NUL $contents['details']['#markup'] = t('Continue with checkout to complete payment.'); } + $form_state['uc_ajax']['uc_payment']['panes']['billing']['address']['billing_country'] = 'uc_payment_checkout_payment_methods'; + $form_state['uc_ajax']['uc_payment']['panes']['delivery']['address']['delivery_country'] = 'uc_payment_checkout_payment_methods'; + return array('description' => $description, 'contents' => $contents); case 'process': @@ -142,18 +145,6 @@ function uc_payment_checkout_payment_details($form, $form_state) { } /** - * Implements hook_uc_ajax_attach(). - */ -function uc_payment_uc_ajax_attach($form, $form_state) { - if ($form['#form_id'] == 'uc_cart_checkout_form') { - $fields = array(); - $fields['panes']['billing']['address']['billing_country'] = 'uc_payment_checkout_payment_methods'; - $fields['panes']['delivery']['address']['delivery_country'] = 'uc_payment_checkout_payment_methods'; - return $fields; - } -} - -/** * AJAX callback for updating the list of payment methods. */ function uc_payment_checkout_payment_methods($form, $form_state) { diff --git a/shipping/uc_quote/uc_quote.module b/shipping/uc_quote/uc_quote.module index 9b2f407..63570c4 100644 --- a/shipping/uc_quote/uc_quote.module +++ b/shipping/uc_quote/uc_quote.module @@ -241,28 +241,6 @@ function uc_quote_form_alter(&$form, &$form_state, $form_id) { } /** - * Implements hook_uc_ajax_attach(). - */ -function uc_quote_uc_ajax_attach($form, $form_state) { - if ($form['#form_id'] == 'uc_cart_checkout_form') { - $fields = array(); - $fields['panes']['delivery']['address']['delivery_country'] = 'uc_quote_checkout_returned_rates'; - $fields['panes']['delivery']['address']['delivery_postal_code'] = 'uc_quote_checkout_returned_rates'; - $fields['panes']['delivery']['select_address'] = 'uc_quote_checkout_returned_rates'; - - if (isset($form['panes']['payment']['line_items'])) { - $fields['panes']['quotes']['quotes']['quote_option'] = 'uc_payment_get_totals'; - } - return $fields; - } - elseif ($form['#form_id'] == 'uc_order_edit_form') { - $fields = array(); - $fields['ship_to']['delivery_country'] = 'uc_quote_order_returned_rates'; - return $fields; - } -} - -/** * Implements hook_uc_cart_pane(). */ function uc_quote_uc_cart_pane($items) { @@ -598,6 +576,11 @@ function uc_checkout_pane_quotes($op, &$order, $form = NULL, &$form_state = NULL $contents['quotes'] += $order->quote_form; + $form_state['uc_ajax']['uc_quote']['panes']['delivery']['address']['delivery_country'] = 'uc_quote_checkout_returned_rates'; + $form_state['uc_ajax']['uc_quote']['panes']['delivery']['address']['delivery_postal_code'] = 'uc_quote_checkout_returned_rates'; + $form_state['uc_ajax']['uc_quote']['panes']['delivery']['select_address'] = 'uc_quote_checkout_returned_rates'; + $form_state['uc_ajax']['uc_quote']['panes']['quotes']['quotes']['quote_option'] = 'uc_payment_get_totals'; + return array('description' => $description, 'contents' => $contents); case 'prepare': @@ -727,6 +710,8 @@ function uc_order_pane_quotes($op, $order, &$form = NULL, &$form_state = NULL) { ); } + $form_state['uc_ajax']['uc_quote']['ship_to']['delivery_country'] = 'uc_quote_order_returned_rates'; + return $form; case 'edit-theme': diff --git a/uc_cart/uc_cart.pages.inc b/uc_cart/uc_cart.pages.inc index 262696c..e738238 100644 --- a/uc_cart/uc_cart.pages.inc +++ b/uc_cart/uc_cart.pages.inc @@ -279,7 +279,7 @@ function uc_cart_checkout_form($form, &$form_state, $order) { '#type' => 'submit', '#value' => t('Review order'), ); - $form['#process'] = array('uc_ajax_attach_process_form'); + $form['#process'][] = 'uc_ajax_process_form'; unset($_SESSION['uc_checkout'][$order->order_id]); diff --git a/uc_order/uc_order.admin.inc b/uc_order/uc_order.admin.inc index ef7b1fa..e4c79a4 100644 --- a/uc_order/uc_order.admin.inc +++ b/uc_order/uc_order.admin.inc @@ -1057,7 +1057,7 @@ function uc_order_edit_form($form, &$form_state, $order) { } field_attach_form('uc_order', $order, $form, $form_state); - $form['#process'] = array('uc_ajax_attach_process_form'); + $form['#process'][] = 'uc_ajax_process_form'; return $form; } diff --git a/uc_store/includes/uc_ajax_attach.inc b/uc_store/includes/uc_ajax_attach.inc index eb3ce14..19f19ff 100644 --- a/uc_store/includes/uc_ajax_attach.inc +++ b/uc_store/includes/uc_ajax_attach.inc @@ -1,13 +1,8 @@ $fields) { + $callback = drupal_array_get_nested_value($fields, $parents); + if (is_string($callback)) { + $callbacks[] = $callback; + } + } + + if ($callbacks) { if (!empty($element['#ajax'])) { - array_unshift($list, $element['#ajax']['callback']); + array_unshift($callbacks, $element['#ajax']['callback']); } else { $element['#ajax'] = array(); } $element['#ajax'] = array_merge($element['#ajax'], array( - 'callback' => 'uc_ajax_attach_multiplex', - 'list' => $list, + 'callback' => 'uc_ajax_multiplex', + 'list' => $callbacks, )); - //dpm($element); } } @@ -51,10 +54,9 @@ function uc_ajax_attach_process_form($form, &$form_state) { /** * Ajax callback multiplexer. * - * Processes a list of Ajax commands attached to the triggering element - * via hook_uc_ajax_attach(). + * Processes a set of Ajax commands attached to the triggering element. */ -function uc_ajax_attach_multiplex($form, $form_state) { +function uc_ajax_multiplex($form, $form_state) { $element = $form_state['triggering_element']; if (!empty($element['#ajax']['list'])) { $commands = array(); diff --git a/uc_store/uc_store.api.php b/uc_store/uc_store.api.php index f43f9a5..8689326 100644 --- a/uc_store/uc_store.api.php +++ b/uc_store/uc_store.api.php @@ -11,30 +11,6 @@ */ /** - * Allows modules to add ajax callbacks to form elements in an orderly manner. The callbacks - * are invoked in module weight order to generate a list of ajax commands which are then returned to - * the page. Note that this hook is invoked before the form has been completely processed, so children - * of elements which are expanded (like 'radios') will not yet be present in the form. However, if you - * know the names of these elements, you may still specify ajax callbacks to be attached to them. - * - * @param $form - * The form to which ajax is being attached. - * @param $form_state - * The $form_state array. - * - * @return - * An nested array of ajax callbacks. The keys of this array must match the parent keys of the element to which - * ajax is being attached. - */ -function hook_uc_ajax_attach($form, $form_state) { - if ($form['#form_id'] == 'uc_cart_checkout_form') { - $fields = array(); - $fields['panes']['delivery']['address']['delivery_country'] = 'mymodule_delivery_country_ajax'; - return $fields; - } -} - -/** * Allows modules to alter the TAPIr table after the rows are populated. * * The example below adds a value for the custom 'designer' column to the table -- 1.7.4.1 From fee8c68a55ca23ccb3cbff3791e08d669961f20c Mon Sep 17 00:00:00 2001 From: Dave Long Date: Wed, 11 Apr 2012 23:01:43 +0100 Subject: [PATCH 9/9] Use form_load_include() for Ajax forms. --- uc_cart/uc_cart.pages.inc | 2 ++ uc_order/uc_order.admin.inc | 3 +++ uc_store/uc_store.module | 1 - 3 files changed, 5 insertions(+), 1 deletions(-) diff --git a/uc_cart/uc_cart.pages.inc b/uc_cart/uc_cart.pages.inc index e738238..2c476d6 100644 --- a/uc_cart/uc_cart.pages.inc +++ b/uc_cart/uc_cart.pages.inc @@ -279,6 +279,8 @@ function uc_cart_checkout_form($form, &$form_state, $order) { '#type' => 'submit', '#value' => t('Review order'), ); + + form_load_include($form_state, 'inc', 'uc_store', 'includes/uc_ajax_attach'); $form['#process'][] = 'uc_ajax_process_form'; unset($_SESSION['uc_checkout'][$order->order_id]); diff --git a/uc_order/uc_order.admin.inc b/uc_order/uc_order.admin.inc index e4c79a4..523799c 100644 --- a/uc_order/uc_order.admin.inc +++ b/uc_order/uc_order.admin.inc @@ -1057,7 +1057,10 @@ function uc_order_edit_form($form, &$form_state, $order) { } field_attach_form('uc_order', $order, $form, $form_state); + + form_load_include($form_state, 'inc', 'uc_store', 'includes/uc_ajax_attach'); $form['#process'][] = 'uc_ajax_process_form'; + return $form; } diff --git a/uc_store/uc_store.module b/uc_store/uc_store.module index 9bb3ef7..cada91c 100644 --- a/uc_store/uc_store.module +++ b/uc_store/uc_store.module @@ -224,7 +224,6 @@ function uc_store_admin_access() { */ function uc_store_init() { module_load_include('inc', 'uc_store', 'includes/tapir'); - module_load_include('inc', 'uc_store', 'includes/uc_ajax_attach'); global $conf; $conf['i18n_variables'][] = 'uc_store_name'; -- 1.7.4.1