简体   繁体   中英

Drupal 7 AJAX Call via hook_menu

So, I am trying to get my new pane on the Ubercart Checkout page to update whenever someone chooses a new shipping option. So far I can get this to occur every time I refresh the page after choosing a new shipping option. The next step is to get it working VIA AJAX.

My problem is that the ajax commands are not firing from the AJAX Callback. The div is not being updated. Right now I just have some simple text. Later, I will add the actual form information that I need, which will be a whole other issue. However, I can't even get this test case to work.

I am working on a new feature for the Ubercart FedEx Module for Drupal. I have been working on this for some time now to no avail. I have tried MANY different things, none work.

To be very clear... I KNOW the ajax call is firing. I can even attach a success to the ajax $.get call and get a console output and the drupal variable is set. ONLY the div replace code is not working. All other pieces to this puzzle work.

I get to the ajax call and return to the javascript. I can even attach a success function on the ajax call in the JS and get console output on success. The javascript is not the issue.

// Implements hook_menu()
function uc_fedex_menu() {
  $items = array();
  $items['uc_fedex_jquery_callback/%'] = array(
    'title' => 'My Custom Callback', 
    'description' => 'Listing of blogs.', 
    'page callback' => 'uc_fedex_calendar_jquery_callback', 
    'page arguments' => array(1),
    'access arguments' => array('access content'), 
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );
  return $items;
}

// AJAX callback: Updates calendar
// THIS IS WHERE THE ERROR IS... the variable is set
// But the div content is never replaced.
function uc_fedex_calendar_jquery_callback($argument) {
  variable_set('uc_fedex_shipment_type',$argument);
  $commands[] = ajax_command_replace('#fromdate', "works");
  return array('#type' => 'ajax', '#commands' => $commands);
}

// Actual UI of Calendar Pane
function uc_fedex_uc_checkout_pane_shipdate($op, $order, $form = NULL, &$form_state = NULL) {
    switch ($op) {
    case 'view':
      // Check for shipping quote option without altering Ubercart Core.
      // The $.get line makes the hook_menu call which in turn
      // makes the call back to the above function that has the issue
      drupal_add_js("
      jQuery(function ($) {
      $(document).ready(function() {
      last = 'o';
          setInterval(function() {
           $('#quote input:radio:checked').each(function() {
              if($(this).val() != last){
                last = $(this).val()
                $.get('https://www.fdanconia.com/uc_fedex_jquery_callback/'+ $(this).val());
              }
           });
          }, 500);
        });
      });", 'inline');

      $contents['calendar'] = array(
        '#type' => 'textfield',
        '#title' => t('Choose Your Estimated Arrival Date'),
        '#default_value' => date('m/j/Y',$response[1]),
        '#prefix' => '<div id="fromdate">',
        '#suffix' => '</div>',
      );
      return array('description' => $description, 'contents' => $contents);
    }
}

// Implements hook_uc_checkout_pane().
function uc_fedex_uc_checkout_pane() {
  $panes['calendar'] = array(
    'callback' => 'uc_fedex_uc_checkout_pane_shipdate',
    'title' => t('Shipping Calendar'),
    'desc' => t('A calendar to allow customers to choose shipping date.'),
    'process' => TRUE,
  );
  return $panes;
}

A note about the js, jQuery( function same_func(){} ) is the equivalent of $(document).ready( function same_func() {} )

So the outer jQuery() calls binds a function to document ready. The function fires at document ready, and bind another function to document ready, which already triggered.

Most of the time in Drupal the variable $ is left unattached so you have to explicitly create a method(function) that passes in jQuery as $.

(function($){ 

$ available in here

})(jQuery);

Think of the the above as: 
(function)(variables) where the function takes a variable $ .. 

Or you can think of it like this:

function test ($) {
  $(jquery magic).etc()'
}
test(jQuery);

.. except the function test, and the function call are included on the 'same' line.

Check firebug/console to see if the $.get is being called.

Another debug is to use php's error_log('message') in uc_fedex_calendar_jquery_callback() and watch the apache error.log.

I ended up adding the parameters I need in the response callback and then processing them on the AJAX response from the original call. I just manipulated the DOM using the updated variable data manually with jQuery. I do not think there is a way to do this otherwise without altering Ubercart core, which is unacceptable.

If anyone wants the code I used to fix this, just ask and thou shal receive. (It is kinda long, but I will post here if someone wants it.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM