Kwikecart is a client side shopping cart written with progressive enhancement in mind. Kwikecart generates no markup (use onAdd() which passed you the added item to place the item into the DOM), utilizes modular loading and aims to keep the core script as accessible and easy to work with as possible. The script comes with a simple express.js application (store.js) for local play.
Kwikecart does make some markup assumptions:
Product markup:
* Each product shares a class
* Each product node has an unqiue ID.
Lets assume a product on the page is marked up like the following:
<li class="product" id="product-3423">
<h2 class="product-name">
<a href="">Worlds Best Item</a>
</h2>
<div>
<div class="product-info">
<div class="product-pid">3423</div>
<div class="product-price">$45.00</div>
</div>
</div>
<!-- Our Actions that Kwikecart.js will call on each related call -->
<!-- Kwikecart will only send the unique id and quantity to the server -->
<form method="post" action="./add" name="itemadd">
<div class="itemFields">
<input type="hidden" name="name" value="Worlds Best Item" />
<input type="hidden" name="pid" value="3423" />
<input type="hidden" name="price" value="45.00" />
<input type="hidden" name="quantity" value="1" />
</div>
<button type="submit" name="addtocart">Add to Cart</button>
<button type="submit" name="removecart">Remove</button>
</form>
<form method="get" action="./check" name="itemcheck">
<input type="hidden" name="id" value="3423" />
</form>
</li>
<!-- Checkout, ant fields defined here will be appended -->
<form method="get" action="./checkout" name="checkout"></form>
require({
baseUrl: 'js/'
}, ['js/kwikecart', 'dojo/ready'],
function(store, ready) {
'use strict';
ready(function () {
cart = store.init(); // Success!
// Assume the example code is in here.
});
});
When initializing the cart you can define any of the following options in a passed object:
{
expires: 1, // Cookie expiration
taxMultiplier: 0.06,
currency: 'USD',
// Toggle to pass all form data on each call
sendAll: false,
// Define data that will be sent with all requests
attachFields: [
/*
{name: 'firstName', value: 'MoreOutput'}
*/
],
// Names of related DOM Data
productNode: '.product',
cartItems: '.cart-products',
cartTotal: '.cart-total',
idField: '[name=id]',
priceField: '[name=price]',
nameField: '[name=name]',
quantityField: '[name=quantity]',
// Forms that control the server calls
addForm: '[name=itemadd]',
removeForm: '[name=itemremove]',
checkForm: '[name=itemcheck]',
clearForm: '[name=clearcart]',
totalForm: '[name=totalcart]',
checkoutForm: '[name=checkout]',
/*
XHR Action Override; cart will not call the server.
Define as a url string to override the form action.
*/
addAction: true,
checkoutAction: true,
removeAction: true,
clearAction: true,
totalAction: true,
// Before events -- must return true before an item is added
beforeCheck: null,
beforeRemove: null,
beforeClear: null,
beforeCheckout: null,
beforeAdd: null,
beforeTotal: null,
// On events -- Fire after the item is added and server response received
onCheck: null,
onRemove: null, // Fired each time remove is called
onClear: null, // Fired when clear is called, avoids remove and onEmpty
onCheckout: null,
onAdd: null, // Fired each time an item is added
onDecrement: null, // Fired when an items quantity goes down but not to 0
onIncrement: null, // Fired when an items quantity goes up but not on 1
onTotal: null,
onFirst: null, // Fired when the first item is added into the cart
onEmpty: null, // Fired when the cart reaches zero from 1+
xhrObj: {handleAs: 'json'}
}
After you initalize the plugin you should be good to go.
When a user clicks the 'Add to Cart' it will submit a post request via XHR with the fields outlined within the form. And now cart.items has a reference to item.
There are a few ways to add items other than submitting an item form and each of these methods result in a call to the form action above.
By ID:
cart.add('product-3423');
Single Item:
cart.add({ id: "product-3429", name: "Product7", quantity: 1, price: 325.00});
Array of items:
var products = [
{ id: "product-3423", name: "Product1", quantity: 1, price: 45.00},
{ id: "product-3430", name: "Product8", quantity: 1, price: 145.00}
];
cart.add(products);
cart.add(query('.product'));
If add an item thats aready in the cart without defining a quantity it is incremented by 1.
cart.add('product-3423'); // +1
cart.add('product-3423'); // +1
You can set the quantity by giving the wanted total.
cart.add('product-3423', 100);
Removing items with remove() is the same as adding:
By ID:
cart.remove('product-3423'); // Fully removes item
Array of items:
products = ['product-3423', 'product-3430'];
cart.remove(products); // Fully removes items
Decrementing items appends decrement=true to the add request.
cart.remove('product-3423', 2); // Removes 2 items
Both the remove() and add() functions are actually just referencing set(). set() will not fire any of the add/remove/increment/decrement events.
cart.set('product-3423', 100);
Use clear to remove all items at once:
cart.clear();
cart.remove(); // Calls clear and will fire those events
Removes all but keeps cookie data:
cart.clear(false);
Accessing items as array:
cart.items;
Finding item in the cart, null if its not there:
cart.find('product-3430');
DOM outline to item object:
cart.createItemObj('product-3430');
Items are only stored in the cart/cookie as their object representations. The attached id must match its dom counterpart.
You can query the server to refresh item data with check().
For single item updates, pass in the id. The server should send back the item as JSON.
cart.check('product-3423');
Calling check() without a passed in ID will send the entire client cart to the server
cart.check();
Getting totals:
cart.total(); // Totals the cart on the client
cart.total(true); // Total with server call
Disable cookies by setting the expires option to -1. When building with cookie data each item is added via add().
Before events are fired before the action begins to process. Before events must return true or the action will be halted. On events are fired at the end of action processing.
Events return the values expected in the action, aside from callback, plus any server response. See onAdd below for an example:
beforeCheck: null,
beforeRemove: null,
beforeClear: null,
beforeCheckout: null,
beforeAdd: null,
beforeTotal: null,
onCheck: null,
onRemove: null,
onClear: null,
onCheckout: null,
onAdd: function(itemsPassedToAdd, quantityPassedToAdd, responseFromAddServerCall) {
// Do something
},
onDecrement: null, // Fired when an items quantity goes down but not to 0
onIncrement: null, // Fired when an items quantity goes up but not on 1
onFirst: null,
onTotal: null
To prevent a call to the server toggle the following cart options to false. You can override the post action by passing in a string.
addAction: true,
checkoutAction: true,
removeAction: false, // remove will not call the server
clearAction: '/reset', // clear now requests the 'reset' end point.
totalAction: true