Creating A Slick Ajaxed Add-To-Basket With jQuery And PHP

18°

It is a clear fact that Ajaxed interfaces, if not overused, eases using websites so much.

For an e-commerce website, this can mean a better shopping experience for customers where they can concentrate more on the products which may result in better sales.

jQuery Ajax Shopping Cart

This is a detailed tutorial which shows creating an unobtrusive Ajaxed shopping cart using jQuery & PHP and can guide you to Ajaxify any e-commerce software you may already be using or coding.

The main functions of the cart will be adding/removing items to the basket without the need of refreshing the page & displaying the actions with effects.

Other Add-To-Basket Tutorials Built on This Example:

To try the demo or download the script:

Download

The HTML

Rather than the formatting of the page, as you can design it however you prefer, we'll be focusing on the vital parts which does all the tricks.

HTML For The Product's Wrapper:

[sourcecode language=”html”]

Product1
Krups Coffee Maker
$95

[/sourcecode]

The part we'll focus is the contents inside <div class="productPriceWrapRight"> which wraps the "add-to-basket" button.

The Highlights:

  • a link with onClick="return false; value which means it won't be active if JavaScript is active (to make the script unobtrusive)
  • add-to-basket image has an unique ID: id="featuredProduct_1" which we'll use to understand the button of which product is clicked

HTML For The Basket:

[sourcecode language=”php”]

Your Basket
  •  

[/sourcecode]

The Highlights:

  • we have an empty <span> with id="notificationsLoader" to show a loading image
  • we keep an empty div to be able to insert any data before/after them
  • we call a PHP function: <?php getBasket(); ?> to get the basket data when the page is first loaded.

The JavaScript (jQuery)

We have 2 main jQuery functions:

Function For Adding To Basket:

[sourcecode language=”javascript”]
$(“.productPriceWrapRight a img”).click(function() {
var productIDValSplitter = (this.id).split(“_”);
var productIDVal = productIDValSplitter[1];

$(“#notificationsLoader”).html(‘‘);

$.ajax({
type: “POST”,
url: “inc/functions.php”,
data: { productID: productIDVal, action: “addToBasket”},
success: function(theResponse) {

if( $(“#productID_” + productIDVal).length > 0){
$(“#productID_” + productIDVal).animate({ opacity: 0 }, 500, function() {
$(“#productID_” + productIDVal).before(theResponse).remove();
});
$(“#productID_” + productIDVal).animate({ opacity: 0 }, 500);
$(“#productID_” + productIDVal).animate({ opacity: 1 }, 500);
$(“#notificationsLoader”).empty();
} else {
$(“#basketItemsWrap li:first”).before(theResponse);
$(“#basketItemsWrap li:first”).hide();
$(“#basketItemsWrap li:first”).show(“slow”);
$(“#notificationsLoader”).empty();
}

}
});

});
[/sourcecode]

The Highlights:

  • splitting the ID of the clicked "add-to-basket" image which is "featuredProduct_1" from the "_" character & get the databaseID of the product (1)
  • inserting the loader.gifimage inside the element with id="notificationsLoader"
  • posting a data with Ajax to our functions.php fil which handles all the server-side jobs. 2 data are posted: productID and the action to be done which is addToBasket
  • There are 2 possibilities when the data is posted, the items may already be inside the basket or it may be a new item. So, we have an if clause: if( $("#productID_" + productIDVal).length > 0){ which checks if an element with ID: productID1 (1 is a variable) exists in the page
    •  if it exist:
      • we change the opacity of that object to 0 (make it invisible)
      • load the new <li>product info</li> response that comes from the functions.php
      • remove the original <li>product info</li> object whose opacity was 0
      • and play with the new <li>product info</li> object's opacity to create a blinking effect
      • empty the contents inside id="notificationsLoader" to stop the loading animation
    • if it does not exist:
      • we insert the response from the functions.php before the first hidden <li> and hide it
      • then use jQuery's show function to display it with an effect
      • empty the contents inside id="notificationsLoader" to stop the loading animation

Function For Removing From Basket:

[sourcecode language=”javascript”]
$(“#basketItemsWrap li img”).live(“click”, function(event) {

var productIDValSplitter = (this.id).split(“_”);
var productIDVal = productIDValSplitter[1];

$(“#notificationsLoader”).html(‘‘);

$.ajax({
type: “POST”,
url: “inc/functions.php”,
data: { productID: productIDVal, action: “deleteFromBasket”},
success: function(theResponse) {

$(“#productID_” + productIDVal).hide(“slow”, function() {$(this).remove();});
$(“#notificationsLoader”).empty();

}
});

});

[/sourcecode]

The Highlights:

  • As the objects are inserted to basket via Ajax, the new HTML items inside the basket are normally not loaded to the DOM and we can't reach them via JavaScript. jQuery offers an event named "live" (starting from jQuery 1.3) which loads the new created items to the DOM. So we used this event.
  • All other tasks are similar to adding an item, we splitted the HTML element from the "_" character and got the productID to be deleted and sent it to functions.php via Ajax.

The Database

We have used a MySQL database in this example with 2 tables:

Products:

Add To Basket Products Table

Baskets (for keeping the shopping cart of every different session)

Add To Basket Sessions Table

The PHP

There is nothing complicated on the PHP part.

Handle The Variables:

[sourcecode language=&”php”]
session_start();
$sessionID = $_COOKIE[‘PHPSESSID’];

if($_POST[‘action’] != ” || $_GET[‘action’] != ”) {
if($_POST[‘action’] == ”)
{
$action = $_GET[‘action’];
$productID = $_GET[‘productID’];
$noJavaScript = 1;
} else {
$action = $_POST[‘action’];
$productID = $_POST[‘productID’];
$noJavaScript = 0;
}
}
[/sourcecode]

The Highlights:

  • we create a session variable so every different user will have their own baskets
  • understand if the request comes from a POST (Ajax) or GET (JS disabled) request and get the action & productID variables
  • if it is a GET request we change the value of a variable named $noJavaScript to 1

PHP For Add To Basket:

[sourcecode language=”php”]
if ($action == “addToBasket”){

$productInBasket = 0;
$productTotalPrice = 0;

$query = “SELECT * FROM products WHERE productID = ” . $productID;
$result = mysql_query($query);
$row = mysql_fetch_array( $result );

$productPrice = $row[‘productPrice’];
$productName = $row[‘productName’];

$query = “INSERT INTO baskets (productID, productPrice, basketSession) VALUES (‘$productID’, ‘$productPrice’, ‘$sessionID’)”;
mysql_query($query) or die(‘Error, insert query failed’);

$query = “SELECT * FROM baskets WHERE productID = ” . $productID . ” AND basketSession = ‘” . $sessionID . “‘”;
$result = mysql_query($query) or die(mysql_error());;

while($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
$totalItems = $totalItems + 1;
$productTotalPrice = $productTotalPrice + $row[‘productPrice’];
}

if ($noJavaScript == 1) {
header(“Location: ../index.php”);
} else {
echo (‘

  • ‘ . $productName . ‘(‘ . $totalItems . ‘ items) – $’ . $productTotalPrice . ‘
  • ‘);
    }

    }

    [/sourcecode]

    The Highlights:

    • we insert the product to the database. If $noJavaScript to 1 we redirect to the index.php else we create a <li> element including the product's details & echo it so we can insert it via jQuery.

    PHP For Delete From Basket:

    [sourcecode language=”php”]
    if ($action == “deleteFromBasket”){

    $query = “DELETE FROM baskets WHERE productID = ” . $productID . ” AND basketSession = ‘” . $sessionID . “‘”;
    mysql_query($query) or die(‘Error, delete query failed’);

    if ($noJavaScript == 1) {
    header(“Location: ../index.php”);
    }
    }
    [/sourcecode]

    The Highlights:

    • we delete the product to the database. If $noJavaScript to 1 we redirect to the index.php

    PHP For Getting The Basket (For Initial Load)

    Like mentioned before, we create a function to get the basket's current situation, so it can be loaded in the initial loading of the page.

    [sourcecode language=”php”]
    function getBasket(){

    session_start();
    $sessionID = $_COOKIE[‘PHPSESSID’];

    $query = “SELECT * FROM baskets WHERE basketSession = ‘” . $sessionID . “‘ GROUP BY productID ORDER By basketID DESC”;
    $result = mysql_query($query);
    //echo $query;

    while($row = mysql_fetch_array($result, MYSQL_ASSOC))
    {

    $query2 = “SELECT * FROM products WHERE productID = ” . $row[‘productID’];
    $result2 = mysql_query($query2);
    $row2 = mysql_fetch_array( $result2 );

    $productID = $row2[‘productID’];
    $productPrice = $row2[‘productPrice’];
    $productName = $row2[‘productName’];

    $query2 = “SELECT COUNT(*) AS totalItems FROM baskets WHERE basketSession = ‘” . $sessionID . “‘ AND productID = ” . $productID;
    $result2 = mysql_query($query2);
    $totalItems = $row2[‘totalItems’];
    $basketText = $basketText . ‘

  • ‘ . $productName . ‘(‘ . $totalItems . ‘ items) – $’ . ($totalItems * $productPrice) . ‘
  • ‘;

    }
    echo $basketText;
    }
    [/sourcecode]

    The Highlights:

    • This is a standard PHP function which creates the HTML for the items in the basket with a loop

    And, the Ajaxed basket built with jQuery & PHP is ready-to-use.

    P.S. To make the example work on your side, you should be creating a new database with the jBasket.sql file inside the download package & configure the database connection information inside "inc/db.php" file.

    60 Comments
    1. Reply Ronald July 27, 2009 at 3:33 AM

      Good stuff, I can definitely use this for an order page I’m making. But, although being a loyal RSS reader, where can I find the DL link? And how do you know I am that loyal RSS reader? 😉

      thanks anyway, keep up the good work!

      (also, your /images/ButtonTransparent.png down here looks a bit squeezed)

    2. Reply Umut M. July 27, 2009 at 3:42 AM

      @Ronald,
      Happy to hear that it may be helpful.

      For the download:
      When reading the latest post via RSS (this post in this case), at the bottom of the post, there is a title: “Special Downloads”. It is the first item under that title: “Ajaxed Add-To-Basket Scenarios With jQuery And PHP”.

    3. Reply Ronald July 27, 2009 at 3:56 AM

      Ok, yep, clever one. I usually scan the RSS intros in Google Reader and then click through to your site, so never noticed that, my bad …

    4. Reply Chris July 27, 2009 at 3:58 AM

      This is an awesome tutorial. Very detailed, thanks much.

      I’m not that into jquery, only used it with scripts I had found but I think I understood how all the logic works.

      Great job, keep up.

    5. Reply Umut M. July 27, 2009 at 4:00 AM

      @Ronald,
      that’s ok, np.

      For the /images/ButtonTransparent.png, can I ask which OS & browser you’re using so I can check it better? Thanks.

    6. Reply Pablo July 27, 2009 at 5:23 AM

      Nice tutorial!

      With a checkout on the back end this will be very useful :0)

    7. Reply Jake Rocheleau July 27, 2009 at 8:03 PM

      Very easy to follow tutorial with AMAZING results! Thanks for sharing, huge fan of the blog.

    8. Reply Ronald July 28, 2009 at 3:17 AM

      @Umut, bugger, I made a screenprint, but deleted it because it’s fine now. It actually was the squeezed “Share and support” button: http://www.webresourcesdepot.com/wp-content/themes/default/images/share-support.png rather than the “Post your comment” button. Using Vista and Firefox.

      But like I said, it’s ok now. Maybe a caching issue.

    9. Reply Umut M. July 28, 2009 at 3:51 AM

      @Ronald,
      It can be about caching. Thanks very much for the effort.

    10. Reply Kiran July 29, 2009 at 4:40 AM

      I think this beats nettuts! A great website with great links! Thanks

    11. Reply Umut M. July 29, 2009 at 5:54 AM

      @Kiran,

      Nettuts is a great website with quality content and both sites are very different than each other.

      And, thanks that you like the content at WRD.

    12. Reply Devang August 3, 2009 at 3:08 AM

      Awesome tutorial.
      Very detailed explanation. I liked the session entry in db to provide each user his own cart.
      I love it.

    13. Reply andreas September 12, 2009 at 7:33 AM

      What i must do if i want to clear the basket and to show the total price off all products ?
      Thanks

    14. Reply Umut M. September 12, 2009 at 4:50 PM

      @andreas,

      I think the best options would be:

      – sending a request similar to deleting 1 product but the PHP page should be coded to delete all..
      – wrapping the prices of the products in a with a special class and finding th esum of the contents of the objects with that class..

      These will easily complete what you need but requires some coding. Hope the ideas help.

    15. Reply Martin Sandhu September 14, 2009 at 5:33 AM

      I’m trying to implement your script which is great!

      I’m having issues with the animation aspect and was wondering if you had a similer issue?

      Thanks

    16. Reply Umut M. September 14, 2009 at 7:00 AM

      @Martin,

      I didn’t face that. If you can you open the problem you’re facing in detail maybe me or an other reader may help.

    17. Reply JKL September 14, 2009 at 5:41 PM

      Nice tutorial, but i’m wondering what do you do with all those records in the basket table when a session expires?

    18. Reply Umut M. September 15, 2009 at 12:36 AM

      @JKL,

      It can be a good idea to delete the ones which are older than x days via a cron job.

    19. Reply Austin September 18, 2009 at 10:33 PM

      I’m a little confused… At what point does this code set the basket variable PHPSESSID? From what I can tell there is no where it is explicitly set.

    20. Reply Untit1ed October 5, 2009 at 4:55 PM

      I don’t know what I did wrong, but I have a problem with animation. When I add a product to my basket sometimes it doesn’t update quantity, but adds another line to my basket even if this kind of product already stored there. It gets fixed, products are grouped together, when I reload the page.

    21. Reply Untit1ed October 5, 2009 at 5:13 PM

      I apologize, it was my bad =)

    22. Reply kale October 6, 2009 at 5:52 AM

      very nice stuff, i would like to add a checkout options at the end where customer fills in his/her details and the details will be send to email? how can i do that, is there any tutorial or scripts ?

    23. Reply Umut M. October 6, 2009 at 6:26 AM

      @kale,
      The code only presents the “add to basket” part and you must be hardcoding that functionality.

    24. Reply Martin Sandhu October 8, 2009 at 7:44 AM

      Thanks for the reply back. The issue can be seen at:

      http://www.hpieurope.com/clearance/ which is a test site I implemented the script into. If you add an item into the basket it wont show the animation but will add it to the basket when the page has refreshed.

      Thanks

      Martin

    25. Reply Adam Morland October 8, 2009 at 5:10 PM

      Could anybody help out please?

      How can i modify this so that if the basket is empty it displays a message saying “your basket is empty. blah blah blah” This disappears when you add the first product, and would reappear if you removed all products from your basket

      Many thanks
      /Adam

    26. Reply Umut M. October 9, 2009 at 2:52 AM

      @Martin,

      Although not sure, it must be something with the PHP file not generating the HTML to be inserted. Suggest checking that part.

    27. Reply Casey October 16, 2009 at 4:34 PM

      Great Cart, but i’m having an issue with the getBasket() on line 74.

      I’m getting this “Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource”

      I can add items to the basket fine, but if i refresh the browser, I cannot get it to show the items in the cart. Once I add an item to the cart, it will show items, but initially it will not show what’s in my cart.

      not posting any code, because I haven’t changed anything to the initial downloaded code. Just having trouble getting it to work like the demo.

    28. Reply Stevie Burns October 22, 2009 at 8:39 AM

      Crackin example… Problem I have is this… I’m using your standard example which works perfectly (as they all do) in Firefox, but its failing in IE. When I say failing its adding duplicate values, 1 click to “Add to Basket” adds 2 items. The version of IE is 7 but I can’t see any reason why this would be the case.

      Using xammp as the Apache, PHP and MySQL environment.

      Hope this is a simple fix, ill look at it again and see if there is something im missing? 🙁

      Cheers
      Stevie

    29. Reply ZelkiN October 27, 2009 at 6:11 AM

      Great Jobs but php4 :s, its very hard to adapt this script on PHP5 object :s

      See u late @ wrd ++

      http://www.whitebloc.com
      http://www.whitebloc.fr

    30. Reply Mr E Commerce November 25, 2009 at 4:19 AM

      @JKL,

      A lot about real marketing is about data. Un-purchased baskets are valuable pieces of data; A successful business will contantly anaylse every aspect of data to help refine a better website, a better deal and better income from more customers.

      Peace 🙂

    31. Reply Sartre December 2, 2009 at 4:46 AM

      Thanks for this script 🙂
      Do you know how can I modify this script to affich just the number of product in my cart (and not the detail) ?
      Thanks 🙂

    32. Reply Bisvan December 2, 2009 at 4:57 AM

      Is it possible to display in another place in the same page juste the “total number of product” in my basket ?

    33. Reply Chris January 10, 2010 at 8:13 AM

      how can I integrate options for a product. For example shirt sizes: small, Medium, Large, XL

      I also, wanted to have the end user enter a price that they want to pay for the product…this is wierd, but I am a not for profit and we have to suggest a donation and the end user has to put in what they want.

      Thanks in advance. This is a sweet example.

    34. Reply Anes January 20, 2010 at 4:30 AM

      Great Script! Is it possible that user enter a price for product? It would be very helpful fo me.

      Thanks in advance.

    35. Reply Umut M. January 20, 2010 at 5:03 PM

      @Chris & @Anes,

      You can add any extra input.

      After adding input fields, you’ll need to improve the line below to handle the values of new inputs (check how productIDVal is created) and handle them on the PHP side too.

      data: { productID: productIDVal, action: “addToBasket”},

      Bests.

    36. Reply miguel rojas March 2, 2010 at 8:49 AM

      Hello. great Job, any question . . when i want add more than 2 product in the basket this show …by example… Krups Coffee Maker(2 items) – $190…. OK… FINE…

      but if i want delete only one item Krups Coffee Maker… the SCRIPT delete all item Krups Coffee Maker in the basket….

      i think is very important a new textfield “amount “… and modify this script for delete item by item when the user does click on X (the red icon ) icon on the BASKET

    37. Reply Michael March 22, 2010 at 9:13 AM

      Hi, 1st of Gr8 script, I’m having problems though with the if nojavascript then ../index.php since i’m working with a dynamic cartloading from a search result.

      So that if a person clicks on the first item and adds it to cart he can stay on the same page but if he has deleted it from the cart whilst in the search page, it should not load back to index.php but to the search results page.

      With this problem i’m having that even though jquery works with the sliding and all, once an item is added to cart, it starts to animate but resets instantly.

      10x for your help

    38. Reply johnny March 31, 2010 at 7:52 AM

      very good script, but it must have somewhere a total price. Which code we must add to display the total price?

    39. Reply $$$$ May 10, 2010 at 2:02 PM

      where can I download the files?!?

    40. Reply Umut M. May 11, 2010 at 4:23 AM

      @johnny,
      You should be running a query for the items in the basket and displaying the item’s price*quantity after every add/delete action.

      @$$$$,
      Once subscribed to the RSS feed and wile reading any WRD article from the feed, you can find it under the title “Special Downloads” at the bottom of every article.

    41. Reply Roy May 13, 2010 at 5:26 PM

      Great tut!! I have a question though. I am trying to implement something similar and was wondering where in the code dictates the added item will go on top in the cart or to the bottom?

      Your demo shows the item going to the top. This is what I want to do however on my cart, it goes to the bottom. Which part of the code can I change to make this happen?

      Thanks…

    42. Reply Umut M. May 14, 2010 at 12:29 AM

      @Roy,

      It is this part:

      $(“#basketItemsWrap li:first”).before(theResponse);

      which simply inserts the Ajax response before the first “li” element.

    43. Reply Roy May 14, 2010 at 9:26 PM

      Thanks for the reply however my code is not exactly same as your code so I wouldn’t know where to put that.. Here is the snippet for mine. If you can point it out, that would be great!

      `jQuery(‘a.add_product’).click( function() {
      form_values = jQuery(“form”, jQuery(this).parent()).serialize();

      jQuery.post( ‘index.php?ajax=true’, form_values, function(returned_data) {
      eval(returned_data);
      }
      return false;

      });
      });
      `

    44. Reply hans May 25, 2010 at 2:27 PM

      First of all thanks for the great script! I’ve troubles when cookies are disabled in a browser.

      It’s possible then to insert records in the baskets-table with an empty basketSession-field. As a result those records are shown to every user to the website when calling getbaskets. Does anyone have a solution for this.

      Thanks in advance
      Hans

    45. Reply Robin Henriksson June 1, 2010 at 10:07 AM

      Hi!

      I have one more GET variable in the action link of the product. How can i get it into this session of the JS file:
      $(“.productPriceWrapRight a img”).click(function() {}
      to send it with the $.ajax data?

      Please give an example to get the href from the link at the same product you get the image information from. I know how to split it afterwards.

      Best Regards
      Robin

    46. Reply jay-arr July 1, 2010 at 1:57 AM

      Hi,

      I downloaded the files for this tutorial but when I execute the index.php file (I renamed it to index.htm?) the page loads but when I clicked the add to basket button, nothing happen to your basket table. maybe because of the database? I created the database but I don’t know how to make a connection? I am new to web programming. thanks.

      Regards,
      jay-arr

    47. Reply Umut M. July 1, 2010 at 2:42 AM

      @jay-arr,

      I suggest you check the response with Firebug which will probably help you view the error.

    48. Reply Jose Tapia August 22, 2010 at 10:23 PM

      Great and aweson tutorial great for my new web site, thanks a lot buddy

    49. Reply shekhar November 23, 2010 at 12:19 AM

      demo page has error. plz fix it up. i need it now to implement in project.

    50. Reply Umut M. December 7, 2010 at 4:46 AM

      @shekhar,

      It is fixed both in demo and download.

    51. Reply kim January 14, 2011 at 8:44 AM

      Im trying to use this script for a favorite script, so i can select my favorite images, and it will display nicely on the sidebar. When i reload the page, my fav’s are still there, but when i close the page and then re-open, my fav list is empty. How can i fix this?

    52. Reply Umut M. January 14, 2011 at 5:09 PM

      @Kim,

      Sounds like you should be matching the list with the user via cookies, users own database id, etc. Simply, the common method you use the remember users.

    53. Reply Kim January 16, 2011 at 7:42 PM

      I was working on it all day long, but still no luck:( Has anybody a pre-made script for the user problem??:$

    54. Reply Slava February 3, 2011 at 3:53 AM

      Hello!
      I have a problem.
      In my shop product is always in the singular.

      Need to hide the container when the product is placed in the basket and show it when the product is removed from the basket.

      In advanced thanks!

    55. Reply Umut M. February 3, 2011 at 8:48 AM

      @Slava,

      You can accomplish it with the help of show/hide functions of jQuery.

      I suggest digging this example: http://www.webresourcesdepot.com/ajaxed-sliding-shopping-cart-with-jquery/ as it has a similar functionality.

    56. Reply Vladislav May 31, 2011 at 11:21 AM

      This is the best basket I have found.
      I have found also a bug in the src-file: functions.php.
      You have lost the string:
      $row2 = mysql_fetch_array( $result2 );
      before:
      $totalItems = $row2[‘totalItems’];
      in the function: getBasket().

    57. Reply Ulfn February 13, 2012 at 3:36 AM

      Just installed the demo and get follow errors
      Notice: Undefined index: action in C:\xampp\htdocs\jBasket\standard\inc\functions.php on line 7
      same for line 20, line 54, line 67, line 74, line 91
      Would be grateful for help.

    58. Reply Ankei February 22, 2012 at 8:51 AM

      Hi! I’ve downloaded your demo but it has several errors like ‘Ulfn’ posted there are undefined index, how do i fix these errors? Please reply. Thanks!

    59. Reply hans October 13, 2012 at 2:14 PM

      Ulfn and Ankei

      Probably to do with new php-versions.

      for action add this to functions.php
      if (!isset($_POST[‘action’]))
      {
      $_POST[‘action’] = “undefine”;
      }

    60. Reply paja June 23, 2013 at 2:28 PM

      hi, can you tel me how i can make #notificationsLoader to be visible for a longer time? for example 2- seconds? thanks

    Leave a reply

    Search