I'm new to Ajax
implementation and data-mage-init
implementations in Magento 2.
So what I'm trying to do :
Situation now
When you are in your cart -> URL/checkout/cart/ you need to press the update button in order to update the QTY's in your cart. But since the cart does not remember the quantity's when you have 1 that exceeded current stock and it resets all fields i want to do something to fix that
Requested scenario
So i want to have the Qty in the cart updated when you change the qty itself and not have it updated in bulk with 1 button.
Code right now
So i have my JQuery (to perform the ajax) and pthml fille loaded like this : (module name = Designit/LiveUpdate)
app/code/Designit/LiveUpdate/view/frontend/layout/checkout_cart_index.xml
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<link src="Designit_LiveUpdate::js/LiveUpdate.js"/>
</head>
<referenceBlock name="checkout.cart.form">
<action method="setTemplate">
<argument name="template" xsi:type="string">Designit_LiveUpdate::cart/form.phtml</argument>
</action>
</referenceBlock>
</page>
I made some minor changes to the .pthml like giving the button that does the update right now an ID submitbutton
. I thought is was handy to have control over the .phtml fille since that is where i want to get the data. Nothing special done there so i'm not posting that long code block unless requested.
Now i want to have Ajax
to validate this on each change in the input.qty
field.
Js:
require(['jquery'], function ($) {
$("#submitbutton").hide();
var form = $('form#form-validate');
var qtyfields = $('input.qty');
form.find(qtyfields).each(function () {
console.log("test find fields");
$(this).change(function () {
console.log("test");
$.ajax({
type: "POST",
url: form.attr('action'),
data: form.serialize(),
success: function (response) {
// Here goes the validation ??;
}
});
});
})
});
You can see i have 2 'test' console logs there. One to see if it finds all the QTY fields and one to see if it can detect the change.
What i noticed so far :
- It does give me 6 console logs on page load for each qty field
- It does not give me console logs on change for some reason
- Not sure if my
url: form.attr('action')
is a good choice here
Question
- How can i display the error when the qty field has changed to see live if it is in stock or not? And maybe even output the max stock available.
I thank everyone in advance who wants to put time into this question really really much!
Update
I have managed to have the quantity updated in the cart (not the error message) on change by doing this (do not mind the console.log because those are just for testing):
require(['jquery', 'Magento_Customer/js/customer-data',
'jquery/jquery-storageapi'], function ($) {
// $("#submitbutton").hide();
var form = $('form#form-validate');
var qtyfields = $('input.qty');
$('.page.messages').each(function () {
var thismessage = $(this);
thismessage.attr('id', 'messages');
});
form.find(qtyfields).each(function (e) {
var thisfield = $(this);
$(this).change(function () {
console.log('change detected');
form.submit();
});
});
form.on('submit', function (e) {
e.preventDefault();
$.ajax({
url: form.attr('action'),
data: form.serialize(),
type: 'post',
success: function (res) {
},
error: function () {
console.log('error');
}
});
console.log('form submitted');
});
});
I still need a way to update the error messages.
Update
This is a better way. Still finding a way to update the Shipment calculation
define([
'jquery',
'Magento_Checkout/js/action/get-totals',
'jquery/ui'
], function ($, getTotalsAction) {
"use strict";
$.widget('mage.liveupdate', {
options: {
enabled: true,
qtyfield: 'input.qty',
form : 'form#form-validate'
},
_create: function () {
if (this.options.enabled) {
this._bindqtycart();
}
},
_bindqtycart: function () {
$("#submitbutton").hide();
var form = $(this.options.form);
var qtyfields = $(this.options.qtyfield);
form.find(qtyfields).each(function (e) {
$(this).change(function () {
form.submit();
});
});
form.on('submit', function (e) {
// var thisfield = $(this);
// var thisiteminfo = thisfield.closest(".item-info");
// var thissubtotal = thisiteminfo.children(".subtotal");
// var formsubtotals = $(this).find('.subtotal');
e.preventDefault();
$.ajax({
url: form.attr('action'),
data: form.serialize(),
type: 'post',
success: function (response) {
var deferred = $.Deferred();
getTotalsAction([], deferred);
$('.cart.item').each(function () {
var thiscartitem = $(this);
var subtotal = thiscartitem.find('.subtotal');
var subtotalval = subtotal.find('span.price');
var qty = thiscartitem.find('.qty');
var qtyval = qty.find('input.qty').val();
var price = thiscartitem.find('td.price');
var priceval = price.find('span.price').html();
var priceval = priceval.replace('€ ' , '');
var priceval = priceval.replace(',' , '.');
var subtotalafter = qtyval*priceval;
subtotalval.html('€ ' + (subtotalafter.toFixed(2)));
})
}
});
});
}
});
return $.mage.quantity;
});