Within my application, I would like to only show a link to the the user's cart only if there are products in it.
I was going to use javascript to check the cookie I can see getting set. commerce_cookie
The problem I'm having is how to read that cookie. I realize its encrypted & I'm not accessing the cookie correctly. That's why I'm unable to get and check for any orders. Is there a better way to check the cart dynamically in this way?
I am trying to read it like this:
var cart = getCookie('commerce_cookie');
console.log(cart); // false
// check if there are any products in the cart
if (cart) {
// show the cart icon
} else {
// hide the cart icon
}
function getCookie(cookie) {
if ($.cookie(name)) {
returnJSON.parse($.cookie(name));
}
}
I have read through this thread about LJ Cookies, but I'm still not confident I'm looking for the cookie correctly:
{{ craft.lj_cookies.get( 'commerce_cookie' ) }}
SOLUTION
What I was tying to do was hide the cart icon and only show it (along with item quantity) only if there were items in the cart.
To do this, you'll need a plugin to listen for the onBeforeAddToCart
event.
MyPlugin.php
// Listen for items getting added to the cart.
craft()->on('commerce_cart.onBeforeAddToCart', function (Event $event) {
$cart = craft()->commerce_cart->getCart();
// set expire & other params as needed
$cookie = new HttpCookie('totalQty', $cart->totalQty);
craft()->request->getCookies()->add($cookie->name, $cookie);
});
Then I've got an ajax request that will check if that cookie exists.
jquery
var data = {
'CSRF': $('input[name="CSRF"]').val()
};
$.ajax({
'type': 'post',
'contentType': 'application/x-www-form-urlencoded; charset=UTF-8',
'cache': false,
'data': data,
'url': '/actions/myplugin/checkCookie',
'dataType': 'json',
'timeout': 50000
}).done(function (response) {
// handle response
}).fail(function (error) {
// Total fail.
});
That routes to a controller method within my plugin:
MyPlugin.php
if (craft()->request->isAjaxRequest()) {
return $this->returnJson(craft()->request->getCookie('totalQty'));
}
Here is how I am then handling/updating the UI with the results of that ajax request. I am summarizing my code here, there is more logic than I am listing - just trying to keep the size of this thread below the level of "book".
I am using velocity for my transitions.
jquery
...
var qty = (result.value + 1); // value is zero-based array so +1
$('#icon').velocity('fadeIn', {
'duration': 300,
'display': 'inline-block',
'complete': function () {
$('<div/>', {
'id': 'cartQty',
'text': qty
}).appendTo($('#icon'))
.velocity('transition.bounceIn', {
'duration': 300,
'easing': 'easeInOutSine'
});
}
});
I wasn't able to find an event that listened for the Empty Cart event, so I had to get creative here.
I listen for the "Empty Cart" form submit via jQuery. From there I make another ajax request to my plugin:
jQuery
$('#emptyCartForm').submit(function (event) {
deleteCookie(); // calls an ajax method (below)
});
$.ajax({
'type': 'post',
'contentType': 'application/x-www-form-urlencoded; charset=UTF-8',
'cache': false,
'data': data,
'url': '/actions/myplugin/deleteCookie',
'dataType': 'json',
'timeout': 50000
}).done(function (response) {
// handle response
}).fail(function (error) {
// Total fail.
});
That request makes a call to a controller method within my plugin:
MyPlugin.php
if (craft()->request->isAjaxRequest()) {
craft()->request->deleteCookie('totalQty');
return $this->returnJson(['status' => 'success']);
}
I'm happy to edit or please feel free to edit if there is any way I can improve this technique.