Drupal 7.x & Calling a block from within a module that maintains AJAX functionality

I’m using Drupal 7.x and I’m trying to maintain order consistency between two or more open pages via Commerce (i.e. - if someone has more than one tab or page opened up but adds something to their cart in one of the opened pages, the cart in the other page will only be up-to-date if they refresh that other page). To fix this, I thought it would be nice to generate the cart block I’m sing to display the orders / cart at one specific URL and then use jQuery to clone-over the main cart if and only if anything is different in the cart. I thought that doing this every 5 or 10 seconds would be adequate enough to maintain consistency. The only issue is that whenever I display the cart block from within the module, it seems to lose any AJAX functionality it has in it’s default form (which is the form that gets displayed normally).

The module I’m modifying in all this is here: https://www.drupal.org/project/dc_cart_ajax.

I’ve modified dc_ajax_add_cart.module with the following:

  $items['ajax-cart-block'] = array(
'title' => '',
'description' => 'Your current cart',
'page callback' => 'dc_get_cart',
'access arguments' => array('access content'),
   );

…and in the callback, I have the following:

function dc_get_cart() {
	$block = block_load('dc_ajax_add_cart', "ajax_shopping_cart");
	$output = drupal_render(_block_get_renderable_array(_block_render_blocks(array($block))));
	print $output;
}

The block displays at “http://website.com/?q=ajax-cart-block” as expected but a closer examination reveals that the “ajax-processed” class is missing from various elements that the default, un-screwed-with version of the block normally has.

Any ideas what might cause this? Really all I’m trying to do here is output the block’s normal cart form somewhere at a given URL so that I can use jQuery to clone from it. That’s all. But I can’t do this unless the form is is being displayed exactly like it does in it’s normal form… (I guess my knowledge of module development is somewhat limited and if someone could steer me in the right direction, that would be great.)

When the below page is visited is the only HTML on the page the cart contents ie. no html or body element?

Better yet post a screen shot of that page.

Also, hacking core and contrib modules is going to produce more problems than it will solve. Typically in Drupal there is a way to do things without hacking other peoples code ie. your own custom module and hooks.

I’ve never used that module but in theory you should be able to render the block as you’re doing and fetch it though the drupal.ajax functions and have the behaviors applied. You can’t use the standard jQuery.ajax function you have to use the drupal ajax abstraction layer. The abstraction layer is defined misc/ajax.js.

Thanks for the input, oddz.

What I wound up doing is the following:

1.) Here’s the callback:

function dc_get_cart(){
    return dc_ajax_add_cart_block_view('ajax_shopping_cart');
}

2.) With the above callback, I’m able to tie into the condition responsible for outputting the block. From there, it outputs everything I need! :smile:

The only thing I need to do now is use jQuery to handle the ajax() calls to replace the user forms with the form contents found on that page if it’s different from the user forms, which is proving to be a little challenging but mostly because I haven’t found the right listener to use to listen for DOM changes (I think I need to use live() or something like that but I haven’t figured out how with the setInterval thing I’m using):

var interval = 5000; //Every X seconds...

setInterval(cart_refresh, interval);
function cart_refresh(){
var $cart;

$.ajax({
   'async': false,
   'type': "GET",
   'global': false,
   'dataType': 'text',
   'url': 'current-cart-contents', //My new page URL...
   'success': function(contents){
       $cart = $(contents).find('.content-middle .ajax-shopping-cart-wrapper').html(); //HTML from new page URL...
    }
});

//If $cart is not the same as the new page HTML value, replace it with $cart...
if ($('#block-dc-ajax-add-cart-ajax-shopping-cart .ajax-shopping-cart-wrapper').html() !== $cart) {
    console.log('not same');
    $('#block-dc-ajax-add-cart-ajax-shopping-cart .ajax-shopping-cart-wrapper').html('');
    $('#block-dc-ajax-add-cart-ajax-shopping-cart .ajax-shopping-cart-wrapper').html($cart);
}else{
    console.log('same');
}

}

The only issue is that the $cart and < the element HTML value > I compare it against always return different…

OT: I figure I’ll be making this into my own module, so do you have any insight into what it takes to upload it to Drupal / GIT, etc.? Have you ever done this? Where would a good place be to get some basic info about it?

One of the things that the Drupal.ajax.* abstraction layer is handle applying behaviors once new content is loaded into the page. You need to use the Drupal AJAX wrapper function(s) defined in misc/ajax.js NOT jQuery.ajax as that doesn’t include any of the additional logic necessary to update the state of page for Drupal.

No reason to upload custom modules to Drupal.org unless you’re using makefiles perhaps.

oddz, do you have any links to any specific documentation explaining how to get started with that? (I’ve always just referenced a custom *.js file respective to my given page(s) that need it and then in that file, just put whatever jQuery I need in it… And if I need to compensate for DOM changes, just use live() or whatever event listeners that are needed.)

But from what you’re saying, it sounds like the only way I’ll be able to do this is through this misc/ajax.js? Would you happen to have an example of using this with a a setInterval() function that can display the changes when the DOM changes (like onChange() or live(), etc. can do?)?

(I.e. - setInterval(my_func, interval):wink:

Thanks for the insight, too. I never even realized that something like this could be done with this misc/ajax.js file… Makes me wonder just how often I should’ve used this instead.

The thing is in Drupal ecosystem .jQuery.live() is not used very much. Instead what Drupal coins as “behaviors” are reattached to the DOM when new content is added. Best to work with that system rather than against it.

I don’t. When it comes to these types of things it is best to not be shy and just dig into the code. I only know this because several months back I worked on a prototype running on Drupal that was very AJAX/JavaScript intensive. The answers lie in reading through misc/ajax.js file. You could probably do it withj Query.live() and reattach the behaviors with yourself but you still need to dig through the misc/ajax.js file to figure out what the logic is for that and I wouldn’t consider that approach the “right” way to do things within the context of working in Drupal. if I have some extra time I will take a gander at it.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.