Hi, we are having a little bit of trouble adding ajax to the COMMERCE MODULE Add to Cart form so it changes some elements besides the Shopping Cart.
This is our code in the hook_form_FORM_ID_alter() function to add Ajax support:
$form['#submit'][] = 'MYMODULE_add_to_cart_form_submit';
$form['submit']['#ajax'] = array(
'callback' => 'MYMODULE_add_to_cart_form_ajax',
'wrapper' => 'shoppingcart', // Our Shopping Cart VIEW has an id="shoppingcart".
'method' => 'replace',
'effect' => 'none',
'progress' => array('type' => 'none'), // Don't want any throbber or progress bar.
);
In our submit function the only thing we are doing here is to REBUILD our form. We got this from reading this help http://api.drupal.org/api/drupal/includes--form.inc/function/drupal_rebu...
function MYMODULE_add_to_cart_form_submit($form, &$form_state) {
// This rebuilds the form from cache and invokes the defined #ajax['callback'].
$form_state['rebuild'] = TRUE;
}
So our main problem here is about about Drupal Messages.
If we use this code on our AJAX callback function...
function MYMODULE_add_to_cart_form_ajax($form, $form_state) {
$uid = $form['uid']['#value'];
$cart_order = commerce_cart_order_load($uid);
$shoppingcart = commerce_embed_view('commerce_cart_block', 'default', array($cart_order->order_id));
return $shoppingcart;
}
...then the Shopping Cart View is updated correctly AND a Drupal Message is added to the Shopping Cart Block, which is not a problem because we can move it to the correct location (via jQuery).
But we want to change more elements apart from the Shopping cart so we tried using Ajax COMMANDS in our AJAX callback function. We re-wrote our function to...
function MYMODULE_add_to_cart_form_ajax($form, $form_state) {
$uid = $form['uid']['#value'];
$cart_order = commerce_cart_order_load($uid);
$shoppingcart = commerce_embed_view('commerce_cart_block', 'default', array($cart_order->order_id));
$commands = array();
$commands[] = ajax_command_replace('#full-node-shoppingcart', $shoppingcart);
// We add here more commands but for the purpose of this example we add only one.
return array('#type' => 'ajax', '#commands' => $commands);
}
...here the Shopping Cart View is updated correctly BUT no message is sent. In the next page full load (F5) it shows as a normal Drupal message. So if a user adds a Product and then goes to his Profile, the "Product has been added to your cart" message is shown in the Profile page. This also applies to validation errors (no stock for that quantity).
Is there a way to use ajax commands and still get the first functionality (the message is sent by Ajax so is not shown in the next page load)?
Thanx in advance.
Comments
Comment #1
rfayI'm not sure you're going to get everything you want here, but you might. The key is to look at ajax_deliver() and see what the default response is and how it packages up the commands on a default response.
You can essentially do the same thing as here but do something different with the status messages.
Comment #2
rfayComment #3
nevets commentedYou could try adding
Comment #4
EndEd commentedHi, thanks both of you :)
We manage to sort this. Here's the new code of our AJAX callback function:
Using theme('status_messages') with no parameters gives us the themed message. This theme function already calls drupal_get_messages() so this is the way.
We had to remove and then add the message wrappper div because using ajax_command_replace only works if there's already a message (so the wrapper is there). This is strange because we read here that if no matched content is found it inserts, and if matched content is found it replaces, but we can't get it to work.
Anyway, thanks again, it was as simple as that.
EDIT: Forgot to say that in our page.tpl.php our $messages variable is printed inside a div with an id of "messages-wrap".
Comment #5
rfayCongratulations and thanks for reporting back.
Comment #5.0
EndEd commentedCorrected a few typos
Comment #7
timodwhit commentedThanks the answer. Appreciate the help.
Comment #8
jason.fisher commentedThanks. I was able to use this with my theme instead of a wrapper:
Comment #9
Atomox commentedThis was a huge help! Thanks.
Comment #9.0
Atomox commentedchanged code to php
Comment #10
f0ns commentedThanks a lot! Man i've been breaking my head over this for quite some time! THANKS!
Comment #11
hurricane66 commentedExtremly well written issue with valuable feedback of possible solutions. It's now 2014, some 3 years after the issue was written, and this documentation are as valid as ever before. Thanks all!
Comment #12
fnandogp commentedSame feeling here #11.
This helped me alot. Thank you guys.
Comment #13
vrwired commented#8 is an easy way to get this done
Comment #14
elijah lynnCrosslinking related forum thread => https://www.drupal.org/node/2081517 (form_set_error message not displayed when using an AJAX field on a form (with a AJAX callback using commands)).
Comment #15
shashwat purav commented$commands[] = ajax_command_prepend(NULL, theme('status_messages'));
This worked for me. :)