jQuery - Update only works for one of many fields - javascript

I'm trying to build a form where if you update any of the inputs, it will update the sum. Right now only the first input is working. I want to use a single class across all of the inputs as the page is dynamic and the ID's can change often.
Here is the jsfiddle:
jsfiddle
Here is the code:
var productCost = function (input, output, changeOn) {
var reloadCalcs = function () {
var sum = 0;
$(input).each(function() {
sum += parseFloat($(input).val());
});
$(output).html(sum);
};
$(function () {
$(changeOn).change(function () {
reloadCalcs();
});
$(changeOn).trigger('change');
});
};
productCost('.product','.sum','input');

By using
sum += parseFloat($(input).val());
You are telling the sum to add the value of .product to itself, since the .product selector will have multiple elements, it will choose the first one.
To fix this, you should use this:
sum += parseFloat($(this).val());

2 changes
var productCost = function(input, output, changeOn) {
var reloadCalcs = function() {
var sum = 0;
$(input).each(function() {
//use the value of current element
sum += (+this.value || 0)
});
$(output).html(sum);
};
//use event delegation to support dynamic elements
$(document).on('change', changeOn, function() {
reloadCalcs();
}).trigger('change');
};
productCost('.product', '.sum', 'input');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="number" class="product" id="design" value="5" />
<br>
<input type="number" class="product" id="features" value="5" />
<br>
<input type="number" class="product" id="performance" value="5" />
<br>
<input type="number" class="product" id="usability" value="5" />
<br>
<h3>TEST</h3>
<div class="sum"></div>
When you use $(input).val(), it will always return the value of the first input element instead of returning the value of current input in the loop

Related

JS doesn't change the value of input

I'm writing cart-box that will change the quantity of products in cart. It works only if I have one box (one product) in cart, but when I have more products in cart it changes the value of the first input only.
This is my html code (earlier in the code I've got loop for my products):
<div class="amount">
<a>
<button type="button" class="minus">-</button>
</a>
<input class="amount-input" th:type="text" th:value="1" th:min="1"/>
<a>
<button type="button" class="plus">+</button>
</a>
</div>
And this is JS code:
$('.minus').click(function () {
var parent = $(this).parent().parent();
var input = parseInt(parent.find(".amount-input").val());
var count = input - 1;
//input['value'] = count;
//parent.closest("input").value = count;
document.querySelector("input").value = count;
});
$('.plus').click(function () {
var parent = $(this).parent().parent();
var input = parseInt(parent.find(".amount-input").val());
var count = input + 1;
//input['value'] = count;
//parent.closest("input").value = count;
document.querySelector("input").value = count;
});
I know that document.querySelector("input").value = count changes the first input only, because it's first on the list, but input['value'] = count doesn't change anything, parent.closest("input").value = count either.
Make sure you use valid HTML, otherwise results are not guaranteed.
Next let's remove duplication and just use the one event listener for both buttons, changing the value added based on the presence of the plus class.
Finally, if you're using jQuery, stick to using jQuery methodology. Also, you are doing nothing here with jQuery that couldn't be done with simple, native, javascript.
//Use one event listener for both
$('.amount button').click(function () {
//Find the nearest ancestor with class amoun
var parent = $(this).closest(".amount");
//Note you need to still use $ with jQuery Objecyd
var input = $(parent).find(".amount-input");
//Set the count based on the class of the button click
var count = parseInt($(input).val()) + ($(this).hasClass("plus") ? 1 : -1 );
//Set the value
$(input).val(count);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="amount">
<button type="button" class="minus">-</button>
<input class="amount-input" type="text" value="1" min="1"/>
<button type="button" class="plus">+</button>
</div>
<div class="amount">
<button type="button" class="minus">-</button>
<input class="amount-input" type="text" value="1" min="1"/>
<button type="button" class="plus">+</button>
</div>

Getting value of unknown number of inputs

I have a site generated mainly in PHP. On one page PHP generates a number of dropdowns, the number of which is depending on items in my DB.
The number of dropdowns can change but I want to be able to count them and get the values for each of them in JS/jQuery.
At the moment the dropdowns all have the same class name but I think I'm going to have to try give them all individual IDs.
I know I could the amount of items like this:
var ammount = $(".myclass").length;
I just need some way of looping through these to get the individual values like this, without just picking up the first value of that class each time:
var input =$(".myclass").value;
I think I'm going to have to go with individual IDs being generated by the PHP but was just wondering if there was another way to do it.
$(".myclass").each(function(i,e) {
console.log(e); //e gives you current item in loop
});
or
$(".myclass").each(function() {
console.log($(this).value);
});
You can get the values in an array, by iterating over all these elements and pushing their values to the array:
var vals = [];
$(".myclass").each(function() {
vals.push($(this).val());
});
If you want to get the sum of all these inputs :
var sum = vals.reduce((a,b) => (+a + +b));
Demo:
var vals = [];
$(".myclass").each(function() {
vals.push($(this).val());
});
console.log(vals);
//Calculating sum of values
var sum = vals.reduce((a,b) => (+a + +b));
console.log(sum);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" class="myclass" value="10" />
<br/>
<input type="text" class="myclass" value="20" />
<br/>
<input type="text" class="myclass" value="30" />
<br/>
<input type="text" class="myclass" value="40" />
<br/>
<input type="text" class="myclass" value="50" />
<br/>

how to get class value

I want to get an updated value from an input field. So I setup a listener
$('.product-quantity input').change( function() {
console.log($(this).parents('.product')[0].id)
var id = $(this).parents('.product')[0].id;
var classgroup = $(this).parents('.product')[0]
for (var i = 0; i < classgroup.childNodes.length; i++){
if (classgroup.childNodes[i].className == "product-quantity") {
console.log(classgroup.childNodes[i])
var target = classgroup.childNodes[i]
}
}
});
classgroup.childNodes[i] output this html
<div class="product-quantity">
<input type="number" id="productquantity" value="1" min="1">
</div>
what I want to do now is get the user input in value. It is suppose to be simple but I can't figure it out
I've tried these but no success
console.log(target.attr('value'))
target.each(function(){
console.log(this.value)
})
how can I get the value number for the output html?
Is this what you are trying to do? You can grab the val of the input itself, and log on change (or whatever you would like to do).
$('#productquantity').change(function() {
console.log($(this).val());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="product-quantity">
<input type="number" id="productquantity" value="1" min="1">
</div>

Add the same event handler to radio buttons and checkboxes

I am trying to have a function add the values of selected check boxes and radio buttons. I have created a function that can add the values of the check boxes and a function for the radio buttons but am having trouble combining the two into one working function. I think my issue is with having both radio and checkbox elements associated with the .click()
My code can be seen here:
https://jsfiddle.net/Buleria28/nz43u7x8/2/
The HTML is:
<input type="checkbox" value="1" />test 1<br/>
<input type="checkbox" value="2" />test 2<br/>
<input type="checkbox" value="3" />test 3<br/>
<input type="radio" name="test" value="1" />test 4
<input type="radio" name="test" value="2" />test 5
<div id='sum'></div>
The jQuery is:
jQuery(document).ready(function($) {
var sum = 0;
$("input:checkbox"),$("input:radio").click(function() {
sum = 0;
$("input:checkbox:checked").each(function(idx, elm) {
sum += parseInt(elm.value, 10);
});
sum = 0;
$("input:radio:checked").each(function(idx, elm) {
sum += parseInt(elm.value, 10);
});
$('#sum').html(sum);
});
});
You're actually using the comma operator and only adding the event handler to the second jQuery object. Instead combine the actual selectors by using a comma in the jQuery constructor's first argument, similar to a CSS selector:
$("input:checkbox, input:radio").click(function() {
…
});
Here you go with the solution https://jsfiddle.net/nz43u7x8/5/
jQuery(document).ready(function($) {
var sum = 0;
$("input:checkbox, input:radio").click(function() {
sum = 0;
$("input:checkbox:checked").each(function(idx, elm) {
sum += parseInt(elm.value, 10);
});
$("input:radio:checked").each(function(idx, elm) {
sum += parseInt(elm.value, 10);
});
$('#sum').html(sum);
});
});

copy label text to input

I have tried several ways to achieve this, but somehow nothing works for this.
How can I copy the "label text" of respective Radio Button, which is selected by user into the input field (Result Box) in real time?
HTML -
<ul class="gfield_radio" id="input_4_4">
Radio Buttons:
<br />
<li class="gchoice_4_0">
<input name="input_4" type="radio" value="2" id="choice_4_0" class="radio_s" tabindex="4">
<label for="choice_4_0">Hi</label>
</li>
<li class="gchoice_4_1">
<input name="input_4" type="radio" value="4" id="choice_4_1" class="radio_s" tabindex="5">
<label for="choice_4_1">Hello</label>
</li>
<li class="gchoice_4_2">
<input name="input_4" type="radio" value="3" id="choice_4_2" class="radio_s" tabindex="6">
<label for="choice_4_2">Aloha</label>
</li>
</ul>
<br />
<div class="ginput_container">
Result Box:
<br />
<input name="input_3" id="input_4_3" type="text" value="" class="medium" tabindex="3">
</div>
My attempts:
$('input').change(function() {
if (this.checked) {
var response = $('label[for="' + this.id + '"]').html();
alert(response);
}
// also this:
// if ($("input[type='radio'].radio_s").is(':checked')) {
// var card_type = $("input[type='radio'].radio_s:checked").val();
// alert('card_type');
// }
});
You need to traverse the DOM from the radio which was clicked to find the nearest label element.
$('.radio_s').change(function() {
$('#input_4_3').val($(this).closest('li').find('label').text());
});
Example fiddle
You could also use $(this).next('label') however, that relies on the position of the label element not changing. My first example means the label can be anywhere within the same li as the radio button and it will work.
Try this:
$('.radio_s').click(function() {
$("#input_4_3").val($("input:checked" ).next().text());
});
Demo: http://jsfiddle.net/WQyEw/3/
This is a slightly tricky question to answer well. The structure of your HTML implies that there may be more than one of these structures on the page. So you may have more than one set of radio buttons with a corresponding checkbox.
I have put some working code into a jsFiddle.
I made one change: all the code you had in your question is now in <div class="container">. You would need as many of these as you had groups of radio buttons and checkboxes.
You can then have jQuery code like this:
$('ul.gfield_radio').on('change', 'input[type="radio"]', function () {
var label = $('label[for="' + this.id + '"]');
$(this).closest('.container').find('input.medium').val(label.text());
});
This code is not tied to the id values in this particular bit of HTML, but would work as many times as necessary throughout the page.
Why to depend on third party library when you can achieve it with plain javascript:
<script>
document.addEventListener('DOMContentLoaded', function () {
var a = document.getElementsByName('input_4');
for (var i = 0; i < a.length; i++) {
document.getElementsByName('input_4')[i].addEventListener('change', function () {
showValue(this);
}, false);
}
}, false);
function showValue(element) {
alert(element.parentNode.getElementsByTagName('label')[0].innerHTML)
}
</script>

Categories