How To Simultaneously Add Multiple Products To A Magento Shopping Cart
Posted September 27th, 2009 in ProgrammingTags: JavaScript, Magento, PHP, Programming
This post is a bit overdue considering the project for which I did this was completed months ago. I finally got around to documenting it. Magento’s product list view lets customers add products to the shopping cart one at a time. The client wanted customers to be able to add multiple products to the shopping cart simultaneously. Given the time constraints for the projects, I created an ad hoc AJAX method to accomplish this feature request.
Adding a product to a Magento (ver. 1.3.1) shopping cart is accomplished through an HTTP GET request. It will look like or similar to this:
/path/to/app/checkout/cart/add?product=[id]&qty=[qty]
That URL is output by the template helper:
$this->getAddToCartUrl($_product)
Since adding a product to the shopping cart is nothing more than a GET request, then all that needs to be done is queue up the URLs of the desired products, make each request in order, and then reload the page when done.
First, in app/design/frontend/
<input type="checkbox" class="input-checkbox add" name="add_<?php echo $_iterator; ?>" id="add_<?php echo $_iterator; ?>" /> <input type="hidden" name="url_<?php echo $_iterator; ?>" id="url_<?php echo $_iterator; ?>" value="<?php echo $this->getAddToCartUrl($_product) ?>" /> <?php if(!$_product->isGrouped()): ?> <input type="text" class="input-text qty" name="qty_<?php echo $_iterator; ?>" id="qty_<?php echo $_iterator; ?>" maxlength="12" value="<?php echo $this->getMinimalQty($_product) ?>" /> <?php endif; ?>
I added this code within the loop that generate the HTML for the product line items for the list. Next, I added the JavaScript that does the actual processing, also within the list section right after the script block that contains: decorateList('products-list', 'none-recursive')
.
<script type="text/javascript"> function processNext(urls, i) { var next = i + 1; $('processing-text').update('Processing item ' + next); if (next < urls.size()) { new Ajax.Request(urls[i], { method: 'get', onComplete: function(transport) { processNext(urls, next); } }); } else { new Ajax.Request(urls[i], { method: 'get', onComplete: function(transport) { window.location.reload(); } }); } } function addItemsToCart() { $('add-items-to-cart').hide(); $('waiting').show(); var addToCartUrls = []; $$('input.add').each(function(e){ if(e.checked == true) { var id = e.readAttribute('id').split('_')[1]; var qty = Number($('qty_' + id).value); if (qty < 1) qty = 1; addToCartUrls.push($('url_' + id).value + 'qty/' + qty); } }); if (addToCartUrls.size() > 0) { processNext(addToCartUrls, 0); } else { $('add-items-to-cart').show(); $('waiting').hide(); alert('Please check off the items you want to add.'); } } </script>
At the bottom of the list I added a submit button.
<div style="margin-bottom:5px; text-align:right;"><button id="add-items-to-cart" class="form-button" onclick="addItemsToCart()"><span><?php echo $this->__('Add Items to Cart') ?></span></button><div id="waiting" style="height:22px; display:none; line-height:22px;"><span id="processing-text">Processing...</span> <img src="<?php echo $this->getSkinUrl().'images/wait22trans.gif'; ?>" width="22" height="22" style="display:inline; vertical-align:middle;"/></div></div>
Clicking the button calls the function addItemsToCart()
. The function hides the button to prevent a double click and unhides the status message. Next, the function determines which checkboxes are checked. For each checked checkbox, the function finds the corresponding URL field and quantity field, concatenates the two values, and stores the new URL in an array. If the length of the array is greater than 0, then the function calls processNext()
, otherwise it displays an error message and resets the submit button.
The function processNext()
first updates the processing message. The function takes the array of URLs and an index, and then creates an AJAX GET request using the URL at the given index in the array. If the AJAX request completes, it calls processNext() with the same array but with an incremented index while the index is less than the array length. If the incremented index is greater than the array length, then that ends the processing and the function reloads the page.
That’s it. If there is anything wrong with the code, it assumes that all the GET requests will complete. Unfortunately, given the time constraints there was no time to account for the scenario where a GET request fails.
Nice work, but when we click on add items to cart, they are going to Recently Viewed Products instead .… Any idea about this, have you updated your codes …
Thanks
I have no idea. I have not updated the code for the latest version of Magento.
Hi Brian,
Thank you for this post. I know this is a little off topic but — Do you have any idea how to implement this idea for the Product Compare function rather than the cart? I.e. if I have multiple products listed,I would like to check off the ones I want to compare and click “Compare Products” and have all the products I checked off added to the compare popup?
Thank you!
Erin
@Erin
Unfortunately, I’m not familiar with the Product Compare function and so I don’t know if this technique is applicable.
Hello.
I’m trying to get it to work on the custom template, where I show all items from all categories by using the getItems () as $ _product):?>
Script processing checked items but does not save the products in cart, the page just restarts.
This is my code:
helper (‘catalog / output’);
$ product = Mage:: getModel (‘catalog / product’);
$ ProductName collection = $ product-> getCollection () -> addAttributeToSelect (‘*’);
$ _product = $ this-> getProduct ();
?>
getItems () as $ _product):?>
<a href = ” getProductUrl ()?>”> getName ()?>
<a href = ” getProductUrl ()?>”> getSku ()?>
getPrice ()?>
Hi! how about update script to use with magento 1.5.0.1 there addtocartlink looks like /checkout/cart/add/product/25/qty/3
Regarding earlier comment, this can be used for a product compare select list in 1.5. Only edit I made was to remove the quantity field from the html and also from the addItemsToCart function. Thanks Brian, very useful.
I also added an ajax loading gif — here’s a great resource with loads of options if you need one: http://www.ajaxload.info/
Regarding on Alex’s comment about multiple products in compare i would like to know how is that possible?I did everything (replace the quantity and replace addtocard with addtocompare (wrong function?), ajax proccessing the items but adding only 1 item. I am trying 4 hours now… any help?
i had a typo error, now its ok