Add to cart with Ajax
I made a simple module (ajax_cart) that alter the add to cart form. The problem is that with this module I can add only one product to the cart. Can someone look at code and try to figure out. Thanks.
Here's the code:
function ajax_cart_form_alter(&$form, &$form_state, $form_id) {
if (strstr($form_id, 'commerce_cart_add_to_cart_form')) {
$form['submit'] = array(
'#value' => t('Add to Cart'),
'#type' => 'submit',
'#ajax' => array(
'callback' => 'ajax_cart_form',
'wrapper' => 'block-commerce-cart-cart',
'method' => 'replace',
'effect' => 'fade',
'progress' => array('type' => 'throbber', 'message' => ''),
),
);
}
}
function ajax_cart_form($form, $form_state){
global $user;
$form_state['rebuild'] = FALSE;
$order_id = commerce_cart_order_id($user->uid);
$cart = commerce_embed_view('commerce_cart_block', 'default', array($order_id));
$commands = array();
$commands[] = ajax_command_replace('#block-commerce-cart-cart .cart-empty-block', $cart);
$commands[] = ajax_command_replace('#block-commerce-cart-cart .view-commerce-cart-block', $cart);
return array('#type' => 'ajax', '#commands' => $commands);
}
Comments
There is a module for doing
There is a module for doing this: http://drupal.org/project/dc_cart_ajax
If you seen it already and you are writing your own for some reason maybe you could find some help in the code.
It doesn't have funcionallity that I need
I looked at that module but it doesn't have funcionallity that I need.
When the user click on the Add to Cart form (on page or in the views) I need to change state in the cart block.
Because of that I made my own module, but I can add only one product to cart.
Thanks
It (the ajax module) does
It (the ajax module) does change the state in the cart block. (At least for me.)
Have you tried this on a clean installation?
subscribe
subscribe
I've found the way to make
I've found the way to make your code work for multiple submissions. It just needed to flush the form caches. It's working very well for me, so anyone looking for ajaxy buttons may use it as well:
<?php
function ajax_cart_form_alter(&$form, &$form_state, $form_id) {
// Add ajax property to Add to Cart button
if (strstr($form_id, 'commerce_cart_add_to_cart_form')) {
$form['submit'] = array(
'#value' => t('Add to Cart'),
'#type' => 'submit',
'#ajax' => array(
'callback' => 'ajax_cart_form',
'wrapper' => 'block-commerce-cart-cart',
'effect' => 'fade',
'progress' => array('type' => 'throbber', 'message' => ''),
),
);
}
}
function ajax_cart_form($form, &$form_state){
global $user;
$order_id = commerce_cart_order_id($user->uid);
$cart = commerce_embed_view('commerce_cart_block', 'default', array($order_id));
$commands = array();
// The next line allows different quantities
// to be submitted each time
unset($form['quantity']['#value']);
// Clear form and form state cache
$form_state = form_state_defaults();
$form_build_id = $_POST['form_build_id'];
form_set_cache($form_build_id, $form, $form_state);
$commands[] = ajax_command_replace('#block-commerce-cart-cart .view-commerce-cart-block', $cart);
$commands[] = ajax_command_replace('#block-commerce-cart-cart .cart-empty-block', $cart);
return array('#type' => 'ajax', '#commands' => $commands);
}
?>
Display add to cart message
If like me you wanted to display the add to cart message you can add something like this to the ajax_cart_form() function
$commands[] = ajax_command_after('.'.$form['#attributes']['class'][1],theme('status_messages'));
It will become
function ajax_cart_form_alter(&$form, &$form_state, $form_id) {
// Add ajax property to Add to Cart button
if (strstr($form_id, 'commerce_cart_add_to_cart_form')) {
$form['submit'] = array(
'#value' => t('Add to Cart'),
'#type' => 'submit',
'#ajax' => array(
'callback' => 'ajax_cart_form',
'wrapper' => 'block-commerce-cart-cart',
'effect' => 'fade',
'progress' => array('type' => 'throbber', 'message' => ''),
),
);
}
}
function ajax_cart_form($form, &$form_state){
global $user;
$order_id = commerce_cart_order_id($user->uid);
$cart = commerce_embed_view('commerce_cart_block', 'default', array($order_id));
$commands = array();
// The next line allows different quantities
// to be submitted each time
unset($form['quantity']['#value']);
// Clear form and form state cache
$form_state = form_state_defaults();
$form_build_id = $_POST['form_build_id'];
form_set_cache($form_build_id, $form, $form_state);
$commands[] = ajax_command_replace('#block-commerce-cart-cart .view-commerce-cart-block', $cart);
$commands[] = ajax_command_replace('#block-commerce-cart-cart .cart-empty-block', $cart);
$commands[] = ajax_command_after('.'.$form['#attributes']['class'][1],theme('status_messages'));
return array('#type' => 'ajax', '#commands' => $commands);
}
Works perfectly for me.
I have 2 products on the same
I have 2 products on the same product display, using the above code it works as expected when you add a product that is on the page when it first loads. But when you change the product (with a dropdown selecting a color in my case) and you try to add this other product, I get the error:
EntityMalformedException: Missing bundle property on entity of type commerce_line_item. in entity_extract_ids() (line 7539 of /var/www/mysite/includes/common.inc)
fixed
I got it fixed with the code below.
Instead of resetting the forms cache, I rebuild the form.
<?php
function ajax_cart_form_alter(&$form, &$form_state, $form_id) {
// Add ajax property to Add to Cart button
if (strstr($form_id, 'commerce_cart_add_to_cart_form')) {
$form['submit'] = array(
'#value' => t('Add to Cart'),
'#type' => 'submit',
'#ajax' => array(
'callback' => 'ajax_cart_form',
'wrapper' => 'block-commerce-cart-cart',
'effect' => 'fade',
'progress' => array('type' => 'throbber', 'message' => ''),
),
);
$form['#submit'][] = 'ajax_cart_form_rebuild_submit';
}
}
function ajax_cart_form_rebuild_submit($form, &$form_state){
$form_state['rebuild'] = TRUE;
}
function ajax_cart_form($form, &$form_state){
global $user;
$order_id = commerce_cart_order_id($user->uid);
$cart = commerce_embed_view('commerce_cart_block', 'default', array($order_id));
$commands = array();
$commands[] = ajax_command_replace('#block-commerce-cart-cart .view-commerce-cart-block', $cart);
$commands[] = ajax_command_replace('#block-commerce-cart-cart .cart-empty-block', $cart);
$commands[] = ajax_command_after('.'.$form['#attributes']['class'][1],theme('status_messages'));
return array('#type' => 'ajax', '#commands' => $commands);
}
?>
A way to improve:
- Is there a way to not display the "Added to cart" message multiple times when the "Add to Cart" button is clicked. The new message should replace the previous message. As the code is now, a new message is displayed each time a new SKU is added from the same product page.
Nice contribution... thank you for this!
replace the 'ajax_command
replace the 'ajax_command_after' with one of the other commands outlined at:
http://api.drupal.org/api/drupal/includes!ajax.inc/group/ajax_commands/7
maybe try 'ajax_command_replace'
ajax_command_remove
With this command I remove the last message before adding the new one:
$commands[] = ajax_command_remove('.messages status');
$commands[] = ajax_command_after('.'.$form['#attributes']['class'][1],theme('status_messages'));
I got some problem if the
I got some problem if the page with the form is put in cache. The only way to solve it as to flush the page cache.
I disabled caching of the page to solve this; Any idea what's the best approach to setup caching of pther pages ? or to disable caching of a specific page ?
thanks.
My Product view is opening in
My Product view is opening in Lightbox2 Overlay using : VIEW DEAL
Above code is not working for Drupal messages in Lightbox2. Drupal messages are not displaying in Lightbox2. When I refresh the page, I can see messages.
Thanks for this discussion.
Helped me lot, in updating cart without refreshing page. Used the same code with little changes for removing product from the cart without refreshing page.
ajax anon
hello guys i have a problem with this code my button doesn't work correctly for anonymous users, works with the second third time.
I made it the easy way and
I made it the easy way and put this in my template.php file... but when i clear the caches it only shows the text "array".
If i just upload it and dont clear caches it works like a charm. Any ideas?
<?php
/* ----------Cart manipulation------------------------------ */
function MYTHEME_form_alter(&$form, &$form_state, $form_id) {
// Add ajax property to Add to Cart button
if (strstr($form_id, 'commerce_cart_add_to_cart_form')) {
$form['submit'] = array(
'#value' => t('BUY TEXT'),
'#type' => 'submit',
'#ajax' => array(
'callback' => 'MYTHEME_form',
'wrapper' => 'block-commerce-cart-cart',
'effect' => 'fade',
'progress' => array('type' => 'throbber', 'message' => ''),
),
);
$form['#submit'][] = 'MYTHEME_form_rebuild_submit';
}
}
function ishop_form_rebuild_submit($form, &$form_state){
$form_state['rebuild'] = TRUE;
}
function MYTHEME_form($form, &$form_state){
global $user;
$order_id = commerce_cart_order_id($user->uid);
$cart = commerce_embed_view('commerce_cart_block', 'default', array($order_id));
$commands = array();
$commands[] = ajax_command_replace('#block-commerce-cart-cart .view-commerce-cart-block', $cart);
$commands[] = ajax_command_replace('#block-commerce-cart-cart .cart-empty-block', $cart);
$commands[] = ajax_command_after('.'.$form['#attributes']['class'][1],theme('status_messages'));
return array('#type' => 'ajax', '#commands' => $commands);
}
/* --------------------------------------------------------- */
?>
Is there a way to make this
Is there a way to make this work without altering other form submissions? I use a global filter on the same page as my catalog and this code makes that filter submission use ajax in addition to the "add-to-cart" buttons.
Have the same problem
Anybody have a solution for this?
great!
This is just great ! Thanks a lot.
Work like a charm!
Thank you for this.
Is there a plan to make it official module?
Got the same idea
https://drupal.org/project/commerce_ajax_cart