I am using magento 2
in mini cart, I am trying to get the event during which product is being added and removed, a specific item not by cart
shown is the item that exists in mini cart, I want that when the user click the “Update” button it is able to retrieve the details of that product being updated in javascript
I am able to get the location of the code here at
vendor/magento/module-checkout/view/frontend/web/template/minicart/item/default.html
I am able to know that this is the correct code
<div class="details-qty qty">
<label class="label" data-bind="i18n: 'Qty', attr: {
for: 'cart-item-'+item_id+'-qty'}"></label>
<input data-bind="attr: {
id: 'cart-item-'+item_id+'-qty',
'data-cart-item': item_id,
'data-item-qty': qty,
'data-cart-item-id': product_sku
}, value: qty"
type="number"
size="4"
class="item-qty cart-item-qty">
<button data-bind="attr: {
id: 'update-cart-item-'+item_id,
'data-cart-item': item_id,
title: $t('Update')
}"
class="update-cart-item"
style="display: none">
<span data-bind="i18n: 'Update'"></span>
</button>
</div>
</div>
because when I try to change the ‘Update’ value to a different value it is reflected into the mini cart
Thus from this view I try to find where the javascript is being triggered , I search for any input that trigger the class ‘update-cart-item’ and able to find the location of code that call the tempate file that contains ‘update-cart-item’ is at here
app/design/frontend/MageBig/martfury/project01/Magento_Checkout/web/js/view/summary/item/details.js
content of the code are as below
define([
'jquery',
'uiComponent',
'Magento_Customer/js/model/authentication-popup',
'Magento_Customer/js/customer-data',
'Magento_Checkout/js/model/quote',
'Magento_Checkout/js/action/get-totals',
'Magento_Checkout/js/model/shipping-service',
'Magento_Checkout/js/model/shipping-rate-registry',
'Magento_Checkout/js/model/resource-url-manager',
'mage/storage',
'Magento_Checkout/js/model/error-processor',
'mage/url',
'Magento_Ui/js/modal/alert',
'Magento_Ui/js/modal/confirm',
'underscore',
'jquery/ui',
'mage/decorate',
'mage/collapsible',
'mage/cookies'
], function ($, Component, authenticationPopup, customerData, quote, getTotalsAction, shippingService, rateRegistry, resourceUrlManager, storage, errorProcessor, url,alert, confirm, _) {
'use strict';
return Component.extend({
shoppingCartUrl: window.checkout.shoppingCartUrl,
defaults: {
template: 'Magento_Checkout/summary/item/details'
},
/**
* @param {Object} quoteItem
* @return {String}
*/
getValue: function (quoteItem)
{
return quoteItem.name;
},
updateItemQtyCheckout: function (data, event)
{
var btnminus = "";
var btnplus = "";
if (event.target.classList[1] == "minus")
{
btnminus = event.currentTarget.dataset.btnMinus;
}
if (event.target.classList[1] == "plus")
{
btnplus = event.currentTarget.dataset.btnPlus;
}
var itemId = event.currentTarget.dataset.cartItem;
// If element is minus and quantity is '1' than remove
var elem = $('#cart-item-' + itemId + '-qty');
if(event.target.classList[1] == 'plus'){
elem.val(parseInt(elem.val()) + 1)
}else if(event.target.classList[1] == 'remove'){
elem.val(0)
}else if(event.target.classList[1] == 'minus'){
elem.val(parseInt(elem.val()) - 1)
}
if ((event.target.classList[1] == "minus" || event.target.classList[1] == "remove") && $('#cart-item-' + itemId + '-qty').val() == '0')
{
var productData = this._getProductById(Number(itemId));
if (!_.isUndefined(productData))
{
var self = this;
var elemr = elem;
self._ajax(url.build('checkout/sidebar/removeItem'), {
'item_id': itemId
}, elemr, self._removeItemAfter);
if (window.location.href === self.shoppingCartUrl)
{
window.location.reload(false);
}
}
}
else
{
this._ajax(url.build('checkout/sidebar/updateItemQty'), {
'item_id': itemId,
'item_qty': $('#cart-item-' + itemId + '-qty').val(),
'item_btn_plus': btnplus,
'item_btn_minus': btnminus
}, elem, this._updateItemQtyAfter);
}
},
_getProductById: function (productId)
{
return _.find(customerData.get('cart')().items, function (item)
{
return productId === Number(item['item_id']);
});
},
_updateItemQtyAfter: function (elem)
{
var productData = this._getProductById(Number(elem.data('cart-item')));
if (!_.isUndefined(productData))
{
$(document).trigger('ajax:updateCartItemQty');
if (window.location.href === this.shoppingCartUrl)
{
window.location.reload(false);
}
}
this._hideItemButton(elem);
this._customerData();
},
_customerData: function ()
{
var deferred = $.Deferred();
getTotalsAction([], deferred);
var sections = ['cart'];
customerData.invalidate(sections);
customerData.reload(sections, true);
var self = this;
self._estimateTotalsAndUpdateRatesCheckout();
},
_ajax: function (url, data, elem, callback)
{
$.extend(data, {
'form_key': $.mage.cookies.get('form_key')
});
$.ajax({
url: url,
data: data,
type: 'post',
dataType: 'json',
context: this,
/** @inheritdoc */
beforeSend: function ()
{
elem.attr('disabled', 'disabled');
},
/** @inheritdoc */
complete: function ()
{
elem.attr('disabled', null);
}
})
.done(function (response)
{
var msg;
if (response.success)
{
callback.call(this, elem, response);
}
else
{
msg = response['error_message'];
if (msg)
{
alert({
content: msg
});
}
}
})
.fail(function (error)
{
console.log(JSON.stringify(error));
});
},
_hideItemButton: function (elem)
{
var itemId = elem.data('cart-item');
$('#update-cart-item-' + itemId).hide('fade', 300);
},
_removeItemAfter: function (elem)
{
var productData = this._getProductById(Number(elem.data('cart-item')));
if (!_.isUndefined(productData))
{
$(document).trigger('ajax:removeFromCart', {
productIds: [productData['product_id']]
});
var sections = ['cart'];
setTimeout(function ()
{
if (customerData.get('cart')().items.length == 0)
{
window.location.reload();
}
}, 2000);
if (window.location.href.indexOf(this.shoppingCartUrl) === 0)
{
window.location.reload();
}
}
this._customerData();
},
_estimateTotalsAndUpdateRatesCheckout: function ()
{
var serviceUrl, payload;
var address = quote.shippingAddress();
shippingService.isLoading(true);
serviceUrl = resourceUrlManager.getUrlForEstimationShippingMethodsForNewAddress(quote);
payload = JSON.stringify({
address: {
'street': address.street,
'city': address.city,
'region_id': address.regionId,
'region': address.region,
'country_id': address.countryId,
'postcode': address.postcode,
'email': address.email,
'customer_id': address.customerId,
'firstname': address.firstname,
'lastname': address.lastname,
'middlename': address.middlename,
'prefix': address.prefix,
'suffix': address.suffix,
'vat_id': address.vatId,
'company': address.company,
'telephone': address.telephone,
'fax': address.fax,
'custom_attributes': address.customAttributes,
'save_in_address_book': address.saveInAddressBook
}
}
);
storage.post(
serviceUrl, payload, false
).done(function (result) {
rateRegistry.set(address.getCacheKey(), result);
shippingService.setShippingRates(result);
}).fail(function (response) {
shippingService.setShippingRates([]);
errorProcessor.process(response);
}).always(function () {
shippingService.isLoading(false);
});
}
});
});
```
this code here render the template from
```
app/design/frontend/MageBig/martfury/project01/Magento_Checkout/web/template/summary/item/details.html
```
and the code content is as below
```
<!-- ko foreach: getRegion('before_details') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!-- /ko -->
<div class="product-item-details">
<div class="product-item-inner">
<div class="product-item-name-block">
<strong class="product-item-name" data-bind="html: $parent.name">
</strong>
<div class="details-qty-price-container">
<div class="details-qty qty">
<label class="label" data-bind="i18n: 'Qty', attr: {for: 'cart-item-'+$parent.item_id+'-qty'}" style="display: none;">
</label>
<button data-bind="attr: {id: 'minus-cart-item-'+$parent.item_id,'data-cart-item': $parent.item_id,'data-btn-minus': 'minus',},click:updateItemQtyCheckout" class="update-cart-item minus">-</button>
<input data-bind="attr: {id: 'cart-item-'+$parent.item_id+'-qty','data-cart-item': $parent.item_id,'data-item-qty': $parent.qty,'data-cart-item-id': $parent.product_sku}, value: $parent.qty"type="number"size="4"class="item-qty cart-item-qty" readonly>
<button data-bind="attr: {id: 'plus-cart-item-'+$parent.item_id,'data-cart-item': $parent.item_id,'data-btn-plus': 'plus'},click:updateItemQtyCheckout" class="update-cart-item plus">+</button>
<button data-bind="attr: {id: 'update-cart-item-'+$parent.item_id,'data-cart-item': $parent.item_id,title: $t('Update')}" class="update-cart-item" style="display: none"><span data-bind="i18n: 'Update'"></span>
</button>
</div>
<!-- ko foreach: getRegion('after_details') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!-- /ko -->
</div>
</div>
<div class="actions">
<button data-bind="attr: {id: 'remove-cart-item-'+$parent.item_id,'data-cart-item': $parent.item_id,'data-btn-remove': 'remove',},click:updateItemQtyCheckout" class="update-cart-item remove">
<svg xmlns="http://www.w3.org/2000/svg" width="10.828" height="10.828" viewBox="0 0 10.828 10.828">
<g id="cross" transform="translate(1.414 1.414)">
<path id="Path_5049" data-name="Path 5049" d="M0,0,8,8" fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="2"/>
<line id="Line_204" data-name="Line 204" y1="8" x2="8" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
</svg>
</button>
</div>
</div>
<!-- ko if: (JSON.parse($parent.options).length > 0)-->
<div class="product options" data-bind="mageInit: {'collapsible':{'openedState': 'active'}}">
<span data-role="title" class="toggle"><!-- ko i18n: 'View Details' --><!-- /ko -->
</span>
<div data-role="content" class="content">
<strong class="subtitle"><!-- ko i18n: 'Options Details' --><!-- /ko -->
</strong>
<dl class="item-options">
<!--ko foreach: JSON.parse($parent.options)-->
<dt class="label" data-bind="text: label">
</dt>
<!-- ko if: ($data.full_view)-->
<dd class="values" data-bind="html: full_view">
</dd>
<!-- /ko -->
<!-- ko ifnot: ($data.full_view)-->
<dd class="values" data-bind="html: value">
</dd>
<!-- /ko -->
<!-- /ko -->
</dl>
</div>
</div>
<!-- /ko -->
</div>
<!-- ko foreach: getRegion('item_message') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!-- /ko -->
this code then render this file below in which you can see that the there is the code
click:updateItemQtyCheckout
which seems to refer to the function during which mini cart item is updated
app/design/frontend/MageBig/martfury/project/Magento_Checkout/web/template/summary/item/details.html
<!-- ko foreach: getRegion('before_details') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!-- /ko -->
<div class="product-item-details">
<div class="product-item-inner">
<div class="product-item-name-block">
<strong class="product-item-name" data-bind="html: $parent.name">
</strong>
<div class="details-qty-price-container">
<div class="details-qty qty">
<label class="label" data-bind="i18n: 'Qty', attr: {for: 'cart-item-'+$parent.item_id+'-qty'}" style="display: none;">
</label>
<button data-bind="attr: {id: 'minus-cart-item-'+$parent.item_id,'data-cart-item': $parent.item_id,'data-btn-minus': 'minus',},click:updateItemQtyCheckout" class="update-cart-item minus">-</button>
<input data-bind="attr: {id: 'cart-item-'+$parent.item_id+'-qty','data-cart-item': $parent.item_id,'data-item-qty': $parent.qty,'data-cart-item-id': $parent.product_sku}, value: $parent.qty"type="number"size="4"class="item-qty cart-item-qty" readonly>
<button data-bind="attr: {id: 'plus-cart-item-'+$parent.item_id,'data-cart-item': $parent.item_id,'data-btn-plus': 'plus'},click:updateItemQtyCheckout" class="update-cart-item plus">+</button>
<button data-bind="attr: {id: 'update-cart-item-'+$parent.item_id,'data-cart-item': $parent.item_id,title: $t('Update')}" class="update-cart-item" style="display: none"><span data-bind="i18n: 'Update'"></span>
</button>
</div>
<!-- ko foreach: getRegion('after_details') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!-- /ko -->
</div>
</div>
<div class="actions">
<button data-bind="attr: {id: 'remove-cart-item-'+$parent.item_id,'data-cart-item': $parent.item_id,'data-btn-remove': 'remove',},click:updateItemQtyCheckout" class="update-cart-item remove">
<svg xmlns="http://www.w3.org/2000/svg" width="10.828" height="10.828" viewBox="0 0 10.828 10.828">
<g id="cross" transform="translate(1.414 1.414)">
<path id="Path_5049" data-name="Path 5049" d="M0,0,8,8" fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="2"/>
<line id="Line_204" data-name="Line 204" y1="8" x2="8" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
</svg>
</button>
</div>
</div>
<!-- ko if: (JSON.parse($parent.options).length > 0)-->
<div class="product options" data-bind="mageInit: {'collapsible':{'openedState': 'active'}}">
<span data-role="title" class="toggle"><!-- ko i18n: 'View Details' --><!-- /ko -->
</span>
<div data-role="content" class="content">
<strong class="subtitle"><!-- ko i18n: 'Options Details' --><!-- /ko -->
</strong>
<dl class="item-options">
<!--ko foreach: JSON.parse($parent.options)-->
<dt class="label" data-bind="text: label">
</dt>
<!-- ko if: ($data.full_view)-->
<dd class="values" data-bind="html: full_view">
</dd>
<!-- /ko -->
<!-- ko ifnot: ($data.full_view)-->
<dd class="values" data-bind="html: value">
</dd>
<!-- /ko -->
<!-- /ko -->
</dl>
</div>
</div>
<!-- /ko -->
</div>
<!-- ko foreach: getRegion('item_message') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!-- /ko -->
I try to put alert(“Test”) and console.log(“Test”); to see if able to capture the code when the minicart product is being updated, unfortunately nothing happened,
I do not understand how the code click:updateItemQtyCheckout
behave and how do I execute javascript code during this event happen
Any help is kindly appreciated whether in helping me understand knockout js or code fixing