Reputation: 580
I have two fields on my product's page, using the class '.qty'. What I want to achieve is that when I enter a value in either of the input fields, both of these input fields are filled with that value.
My current code is this:
function updateProductAmount() {
jQuery('.add-to-cart .qty').each(function() {
var productAmount = this.value;
jQuery('.add-to-cart .qty').val(productAmount);
// Requires more work.
});
}
I'm calling this code with an onchange
inside the input text elements.
This code, however only works one way. When the first input element is changed, it copies the value to the last input element. However, when the last input element is changed, it changes back to the value of the first input element.
Can anyone point out to me what I'm doing wrong and help me out?
Thanks in advance.
Upvotes: 3
Views: 6463
Reputation: 2815
Try the following:
$(document).on('change','.add-to-cart .qty', function(){
$('.add-to-cart .qty').val($(this).val());
});
Upvotes: 4
Reputation: 33306
The value of this
within jQuery's each()
is the value of the object for this iteration of each()
, not the element on which the event was fired. You need to store the value to which you are changing the input prior to entering the each()
.
You then use a second jQuery statement with the each()
with the same selector to change the value. This causes all values to be first changed to the first <input>
's value, then changed to the second <input>
's value, then to the third, etc. However, by the time you get to changing all <input>
values to the second <input>
's value, the second <input>
's value has already been changed to the value of the first <input>
. Effectively, this results in all <input>
s following the value of the first <input>
without being able to change any input other than the first.
Example showing value of this
within each()
:
$('.add-to-cart input.qty').on('input', updateProductAmount);
function updateProductAmount() {
$('.add-to-cart input.qty').each(function() {
console.log('This points to id: ' + this.id + " ::value=" + this.value);
var productAmount = this.value;
$('.add-to-cart .qty').val(productAmount);
// Requires more work.
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="add-to-cart">
<input class="qty" id="firstInput">
<input class="qty" id="secondInput">
</div>
Minimally changed, functional: store productAmount
before the each()
:
$('.add-to-cart input.qty').on('input', updateProductAmount);
function updateProductAmount() {
var productAmount = this.value;
$('.add-to-cart input.qty').each(function() {
$('.add-to-cart .qty').val(productAmount);
// Requires more work.
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="add-to-cart">
<input class="qty" id="firstInput">
<input class="qty" id="secondInput">
</div>
In addition:
.not($(this))
to remove it from the jQuery object over which you are iterating with each()
.You, potentially, are iterating over elements that are not <input>
s. You can change your selector to only select <input>
elements.
Having removed the var productAmount = this.value;
from within your each()
it is no longer necessary to explicitly iterate over the jQuery object using each()
. You can use jQuery's implicit iteration to change the value
using val()
.
$('.add-to-cart input.qty').on('input', updateProductAmount);
function updateProductAmount() {
var productAmount = this.value;
$('.add-to-cart input.qty').not($(this)).val(productAmount);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="add-to-cart">
<input class="qty" id="firstInput">
<input class="qty" id="secondInput">
</div>
each()
, this
will refer to the element on which the event is fired. Thus, there is no need to first store the value in a separate variable. However, if you are expecting to iterate over a large number of elements, then using a separate variable will be slightly faster than getting the value
from the element in each iteration.Final code:
$('.add-to-cart input.qty').on('input', updateProductAmount);
function updateProductAmount() {
$('.add-to-cart input.qty').not($(this)).val(this.value);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="add-to-cart">
<input class="qty" id="firstInput">
<input class="qty" id="secondInput">
</div>
Upvotes: 0
Reputation: 197
The problem here is that you are setting each value for each input. If you trace the code you'll see something like this:
Now, as you can see, if the second input is changed the same order of operations occurs. This means that the first input will be examined first, and its value will be given to all inputs matching the selector, overwriting the value of the second input with the first. Therefore, it doesn't matter what the value of the second input is because by the time the .each gets there it has already been overwritten with the value from input 1.
As others have said, the solution here is to simply find all matching elements you would like to update with jQuery and set them to this.value. Using the jQuery val function updates the value of all matched elements, eliminating the need for a .each loop:
function updateProductAmount() {
$('.add-to-cart .qty').val(this.value);
}
Upvotes: 0
Reputation: 192
Here is a JS fiddle of what you are trying to do.
function updateProductAmount() {
$('.qty').val($(this).val());
}
$(".qty").change(updateProductAmount);
https://jsfiddle.net/ahmedhawas7/zx3sqxft/
Upvotes: 0
Reputation: 12959
Try this :
$(document).ready(function() {
$(".qty").on("input",function(){
$(".qty").not($(this)).val($(this).val());
})
})
Final code :
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<input type="text" class="qty" value="" />
<input type="text" class="qty" value="" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
$(document).ready(function() {
$(".qty").on("input",function(){
$(".qty").not($(this)).val($(this).val());
})
})
</script>
</body>
</html>
Upvotes: 0
Reputation:
If I understand, you need change value of siblings
jQuery( '.add-to-cart .qty' ).on( 'change' , function () {
jQuery( this ).siblings().val( jQuery( this ).val() );
} );
Upvotes: 0
Reputation: 11
Try passing the used inputfield as parameter. ex: to check which field was used. You could also pass a reference to 2nd field (if it is intended that you stick to two fields. Something along the lines should do the trick
<input type="text" value="" name="qty" class="qty" onchange="updateProductAmount(this, jQuery('.add-to-cart'))"/>
<input type="text" value="" name="add-to-cart" class="add-to-cart" onchange="updateProductAmount(this, jQuery('.qty'))"/>
and on the script-part
function updateProductAmount(caller, fieldToChange) {
jQuery(fieldToChange).val(caller.value);
}
Upvotes: 1