Here is the code I want to use to allow user control the product quantity in a shopping cart. The problem is, if there are 2 product or more in the same cart, if I try to increase one product quantity, it will increase all products quantity. I would like to use the foreach function in the jQuery code , I tried to insert PHP $i++ , but it didn’t work.
can someone help please ?
I just want separate product quantity increase/decrease for each product (form)
<?php
if (isset($_POST['submit'])) {
$product_quantity= $_POST['quantity'];
} else {$product_quantity= "1";}
?>
<form class="cart-items-number d-flex ml-auto" method='POST' action=''>
<input type = "submit" value="-" name = "submit" value = "Submit" class="qtyminus btn btn-success btn-sm" field="quantity" >
<input type='text' name='quantity' value='<?php echo $product_quantity; ?>' class='qty form-control' />
<input type = "submit" value='+' name = "submit" value = "Submit" class='qtyplus btn btn-success btn-sm' field='quantity' >
</form>
<form class="cart-items-number d-flex ml-auto" method='POST' action=''>
<input type = "submit" value="-" name = "submit" value = "Submit" class="qtyminus btn btn-success btn-sm" field="quantity" >
<input type='text' name='quantity' value='<?php echo $product_quantity; ?>' class='qty form-control' />
<input type = "submit" value='+' name = "submit" value = "Submit" class='qtyplus btn btn-success btn-sm' field='quantity' >
</form>
<script src="jquery/jquery.min.js"></script>
<script>
jQuery(document).ready(function() {
$('.qtyplus').click(function(e) {
fieldName = $(this).attr('field');
var currentVal = parseInt($('input[name=' + fieldName + ']').val());
if (!isNaN(currentVal)) {
$('input[name=' + fieldName + ']').val(currentVal + 1);
} else {
$('input[name=' + fieldName + ']').val(1);
}
});
$(".qtyminus").click(function(e) {
fieldName = $(this).attr('field');
var currentVal = parseInt($('input[name=' + fieldName + ']').val());
if (!isNaN(currentVal) && currentVal > 1) {
$('input[name=' + fieldName + ']').val(currentVal - 1);
} else {
$('input[name=' + fieldName + ']').val(1);
}
});
});
</script>
2
Answers
In your click event handler you were fetching the input element using a selector in the whole document that was going to return multiple elements.
Instead you should rely on the element triggering the event and query its subtree to address the specific input element for which you intended to increment or decrement the value.
So in your click event handler,
$(this)
will be the button triggering the event, and from there you can select its parent form by doing$parent = $(this).closest('form')
and query its children without involving the whole document by doing$parent.find(/*selector*/)
instead of$(/*selector*/)
Here in this example I also made the function
addToInput
that will handle the logics in general dealing with the clicked$button
and theamount
to add passed as arguments.Plus since you were using input
type="submit"
for your plus and minus buttons, I changed them totype="button"
so that the form won’t be sumitted at each click. Of course if that was your intended behaviour just revert back to original. But yet those two buttons, for each row, were having the same value for thename
attribute and since they belong to the same form, it would be more appropriate to have each one its own name.[EDIT after @Roko’s comment]
As a final note, you were using the attribute
field
in your plus and minus buttons to know the name of the input element that they had to address. Now left aside the fact that, as is, in this exact code, it’s not needed because there’s no ambiguity since it’s the onlyinput type=text
and that condition would be enough to fetch it with no added condition. But yet if you wanted to use such a strategy it was more appropriate to use a data attribute instead:https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes
Since
field
is not a valid attribute for that element as for HTML5 specs.$(".staticParent").on("eventName", ".dynamicChild", fn)
Then refer to the Event delegator parent using
$(evt.delegateTarget)
and to the currently clicked button using$(evt.currentTarget)
(is you use Arrow Function(evt) => {
) , or by using$(this)
if you use Regular Functionfunction(evt) {
name
s, duplicatedvalue
, etc). Don’t use invalid non-HTML5 attributes. Use data-* attributes if really needed. (Not needed for this code to work)Math.max()
input[type=number]
instead, and its native JavaScriptstepUp()
andstepDown()
methods (Read more on MDN)