Skip to content

Instantly share code, notes, and snippets.

@agoradesign
Last active April 12, 2022 15:54
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save agoradesign/d70763c8ba4447b312d04093183d153f to your computer and use it in GitHub Desktop.
Save agoradesign/d70763c8ba4447b312d04093183d153f to your computer and use it in GitHub Desktop.
Drupal Commerce 2.x ajaxified add to cart and wishlist snippets
(function ($, Drupal, drupalSettings) {
Drupal.behaviors.ajaxAddToCart = {
getCsrfToken: function(callback) {
$.get(Drupal.url('rest/session/token'))
.done(function (data) {
callback(data);
});
},
addToCart: function (csrfToken, purchasedEntityType, purchasedEntityId, qty) {
$('body').append('<div class="add-to-cart-ajax-throbber ajax-progress ajax-progress-fullscreen"></div>');
$.ajax({
url: Drupal.url('cart/add?_format=json'),
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': csrfToken
},
data: JSON.stringify([{
purchased_entity_type: purchasedEntityType,
purchased_entity_id: purchasedEntityId,
quantity: qty
}]),
success: function(data) {
var orderItem = data[0];
var $overlay = $('#add-to-cart-overlay');
$overlay.find('.purchased-entity').text(orderItem.title);
$overlay.foundation('open');
Drupal.behaviors.ajaxAddToCart.updateCart();
$('.add-to-cart-ajax-throbber').remove();
}
});
},
updateCart: function() {
var $cartCount = $('.store-action--cart .store-action__link__count');
if ($cartCount.length) {
$.ajax({
url: Drupal.url('cart?_format=json'),
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
success: function(data) {
var cart = data[0];
var count = cart.order_items.reduce(function (previousValue, currentValue) {
return previousValue + parseInt(currentValue.quantity);
}, 0);
$cartCount.text(count);
}
});
}
},
addToWishlist: function (csrfToken, purchasableEntityType, purchasableEntityId, qty) {
$('body').append('<div class="add-to-wishlist-ajax-throbber ajax-progress ajax-progress-fullscreen"></div>');
$.ajax({
url: Drupal.url('wishlist/add?_format=json'),
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': csrfToken
},
data: JSON.stringify([{
purchasable_entity_type: purchasableEntityType,
purchasable_entity_id: purchasableEntityId,
quantity: qty
}]),
success: function(data) {
var wishlistItem = data[0];
var $overlay = $('#add-to-wishlist-overlay');
$overlay.find('.purchasable-entity').text(wishlistItem.title);
$overlay.foundation('open');
Drupal.behaviors.ajaxAddToCart.updateWishlist();
$('.add-to-wishlist-ajax-throbber').remove();
}
});
},
updateWishlist: function() {
var $wishlistCount = $('.store-action--wishlist .store-action__link__count');
if ($wishlistCount.length) {
$.ajax({
url: Drupal.url('wishlist?_format=json'),
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
success: function(data) {
var wishlist = data[0];
var count = wishlist.wishlist_items.reduce(function (previousValue, currentValue) {
return previousValue + parseInt(currentValue.quantity);
}, 0);
$wishlistCount.text(count);
}
});
}
},
attach: function attach(context) {
$(context).find('.add-to-cart-link').once('add-to-cart-link-init').each(function () {
$(this).on('click', function (e) {
e.preventDefault();
var variationId = $(this).data('variation');
Drupal.behaviors.ajaxAddToCart.getCsrfToken(function (csrfToken) {
Drupal.behaviors.ajaxAddToCart.addToCart(csrfToken, 'commerce_product_variation', variationId, 1);
});
});
});
$(context).find('form.add-to-cart-form').once('add-to-cart-form-init').each(function () {
$(this).on('click', '.form-submit', function(e) {
var isWishlistButton = $(this).hasClass('add-to-wishlist-button');
$(this).parents('form').data('button-clicked', isWishlistButton ? 'wishlist' : 'cart');
});
$(this).on('submit', function (e) {
e.preventDefault();
var buttonClicked = $(this).data('button-clicked');
var purchasedEntityType = $(this).data('purchased-entity-type');
var purchasedEntityId = $(this).data('purchased-entity-id');
var qty = $(this).find('input[name="quantity[0][value]"]').val();
Drupal.behaviors.ajaxAddToCart.getCsrfToken(function (csrfToken) {
if (buttonClicked === 'wishlist') {
Drupal.behaviors.ajaxAddToCart.addToWishlist(csrfToken, purchasedEntityType, purchasedEntityId, qty);
}
else {
Drupal.behaviors.ajaxAddToCart.addToCart(csrfToken, purchasedEntityType, purchasedEntityId, qty);
}
});
});
});
$(context).find('.add-to-wishlist-link').once('add-to-wishlist-link-init').each(function () {
$(this).on('click', function (e) {
e.preventDefault();
var variationId = $(this).data('variation');
Drupal.behaviors.ajaxAddToCart.getCsrfToken(function (csrfToken) {
Drupal.behaviors.ajaxAddToCart.addToWishlist(csrfToken, 'commerce_product_variation', variationId, 1);
});
});
});
}
};
})(jQuery, Drupal, drupalSettings);
ajax_add_to_cart:
js:
js/ajax_add_to_cart.js: {}
dependencies:
- core/jquery
- core/jquery.once
- core/drupal
- core/drupalSettings
/**
* Implements hook_form_BASE_FORM_ID_alter() for commerce_order_item_add_to_cart_form.
*/
function MYTHEME_form_commerce_order_item_add_to_cart_form_alter(&$form, FormStateInterface $form_state, $form_id) {
$form['#attached']['library'][] = 'MYTHEME/ajax_add_to_cart';
// Add custom class to form.
$form['#attributes']['class'][] = 'add-to-cart-form';
/** @var \Drupal\commerce_cart\Form\AddToCartForm $form_object */
$form_object = $form_state->getFormObject();
/** @var \Drupal\commerce_order\Entity\OrderItemInterface $order_item */
$order_item = $form_object->getEntity();
$purchased_entity = $order_item->getPurchasedEntity();
$form['#attributes']['data-purchased-entity-type'] = $purchased_entity->getEntityTypeId();
// The order item's purchased entity reference won't be up to date, when a
// different product variation was selected and updated via Ajax. The form
// state stores it to 'selected_variation' then. Our product set entity on the
// other side, does not store such a value, but is the purchasable entity on
// its own. So we can safely take the one from the order item.
$purchased_entity_id = $purchased_entity instanceof ProductVariationInterface ? $form_state->get('selected_variation') : $purchased_entity->id();
$form['#attributes']['data-purchased-entity-id'] = $purchased_entity_id;
}
/**
* Implements template_preprocess_commerce_add_to_cart_link().
*/
function MYTHEME_preprocess_commerce_add_to_cart_link(array &$variables) {
$variables['#attached']['library'][] = 'MYTHEME/ajax_add_to_cart';
}
... at the end of the file:
<div id="add-to-cart-overlay" class="reveal" data-reveal data-close-on-click="false">
<p><span class="purchased-entity"></span> wurde Ihrem Warenkorb hinzugefügt.</p>
<div>
<a class="button" href="{{ path('commerce_cart.page') }}">zum Warenkorb</a><br/>
<a href="#" data-close>Weiter einkaufen</a>
</div>
<button class="close-button" data-close aria-label="Close modal" type="button">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div id="add-to-wishlist-overlay" class="reveal" data-reveal data-close-on-click="false">
<p><span class="purchasable-entity"></span> wurde Ihrer Merkliste hinzugefügt.</p>
<div>
<a class="button" href="{{ path('commerce_wishlist.page') }}">zur Merkliste</a><br/>
<a href="#" data-close>Weiter einkaufen</a>
</div>
<button class="close-button" data-close aria-label="Close modal" type="button">
<span aria-hidden="true">&times;</span>
</button>
</div>
@SahilGidwani
Copy link

Hello @agoradesign team the ajax_add_to_cart.js is throwing the following error in latest version of drupal commerce and drupal(8.9.13)
ajax-erroe
Please refer to the above image.
Can You please guide where, I am going wrong.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment