I have a form with a bunch of inputs set with value zero like
<input type="text" name="qty" size="4" autocomplete="off" class="form-control quantity_wanted text" value="0">
The user then types in quantities of products they want. I want to select the last input where they entered a quantity. I was able to do something similar with checkboxes like this.
$('.product-checkbox:checkbox:checked:last')
But how can I put in a condition for an input box to select the last input with value greater than zero? Thanks.
You could use :not() and the Attribute Selector [attribute]
:not([value='0'])
JavaScript example
let qtyGT0 = [...document.querySelectorAll(".qty:not([value='0'])")].reverse()[0];
// Just to test
if (qtyGT0) qtyGT0.classList.add("red");
.red{ background:red; }
<input class="qty" value="0">
<input class="qty" value="1">
<input class="qty" value="1">
<input class="qty" value="0">
Another JavaScript example
in pure JavaScript ES6 it would look like
let qtyGT0 = [...document.querySelectorAll(".qty")].filter( el => el.value > 0 ).pop();
// Just to test
if (qtyGT0) qtyGT0.classList.add("red");
.red{ background:red; }
<input class="qty" value="0">
<input class="qty" value="1">
<input class="qty" value="1">
<input class="qty" value="0">
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
jQuery:
var $qtyGT0 = $(".qty").filter((i, el) => el.value > 0 ).last();
// Just to test
$qtyGT0.addClass("red");
.red{ background:red; }
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input class="qty" value="0">
<input class="qty" value="1">
<input class="qty" value="1">
<input class="qty" value="0">
http://api.jquery.com/filter/
https://api.jquery.com/last/
A pure JavaScript answer is that you would just iterate them in reverse and stop at the first one you find.
var inputs = document.querySelectorAll("input");
for(var len = inputs.length-1; len >=0; len--){
if(inputs[len].value > 0){
console.log(inputs[len].name);
inputs[len].style.backgroundColor = "yellow";
break;
}
}
<input type="text" name="qty" size="4" autocomplete="off" class="form-control quantity_wanted text" value="1">
<input type="text" name="qty2" size="4" autocomplete="off" class="form-control quantity_wanted text" value="2">
<input type="text" name="qty3" size="4" autocomplete="off" class="form-control quantity_wanted text" value="3">
<input type="text" name="qty4" size="4" autocomplete="off" class="form-control quantity_wanted text" value="0">
Related
I have a collection of inputs
<input type="text" name="item" id="item" value="Name">
<input type="number" name="unit_price" id="unit_price" value="100">
<input type="number" name="qty" id="qty" value="2">
<input type="number" name="discount" id="discount" value="0">
<input type="text" name="item" id="item" value="Name 2">
<input type="number" name="unit_price" id="unit_price" value="200">
<input type="number" name="qty" id="qty" value="5">
<input type="number" name="discount" id="discount" value="10">
I'm trying to loop through all of these inputs to create an object with keys exactly the same as names in my inputs and add those values as values.
So my steps are:
let arr = []
inputs.forEach((elem) => {
console.log(elem.value)
arr.push({
'item': elem.value,
'unit_price': elem.value,
'qty': elem.value,
'discount': elem.value
});
})
EDITED
the expected output should look like this:
arr = [{
'item': 'Name',
'unit_price': '100',
'qty': '2',
'discount': '0',
},
{
'item': 'Name 2',
'unit_price': '200',
'qty': '5',
'discount': '10'
}
]
You can iterate over the input elements in chunks of 4.
let inputs = document.querySelectorAll('input');
let res = [];
let names = ['item', 'unit_price', 'qty', 'discount'];
for (let i = 0; i < inputs.length; i += names.length)
res.push(names.reduce((acc, curr, j) => (acc[curr] = inputs[i + j].value, acc), {}));
console.log(res);
<input type="text" name="item" id="item" value="Name">
<input type="number" name="unit_price" id="unit_price" value="100">
<input type="number" name="qty" id="qty" value="2">
<input type="number" name="discount" id="discount" value="0">
<input type="text" name="item" id="item" value="Name 2">
<input type="number" name="unit_price" id="unit_price" value="200">
<input type="number" name="qty" id="qty" value="5">
<input type="number" name="discount" id="discount" value="10">
Well, maybe you can wrap your inputs inside divs, and then find each block of values and map the values into two objects. Like:
<div id="first">
<input type="text" name="item" id="item" value="Name">
<input type="number" name="unit_price" id="unit_price" value="100">
<input type="number" name="qty" id="qty" value="2">
<input type="number" name="discount" id="discount" value="0">
</div>
<div id="second">
<input type="text" name="item" id="item" value="Name 2">
<input type="number" name="unit_price" id="unit_price" value="200">
<input type="number" name="qty" id="qty" value="5">
<input type="number" name="discount" id="discount" value="10">
</div>
And in JS
const first = {}
const second = {}
document.querySelectorAll('input').forEach( input => {
if (input.parentElement.id === 'first') {
first[input.name] = input.value;
} else {
second[input.name] = input.value;
}
});
console.log(first, second);
If you want two separate objects, you can add a class to the inputs to group them like so.
<input class="item1" type="text" name="item" id="item" value="Name">
<input class="item1" type="number" name="unit_price" id="unit_price" value="100">
<input class="item1" type="number" name="qty" id="qty" value="2">
<input class="item1" type="number" name="discount" id="discount" value="0">
<input class="item2" type="text" name="item" id="item2" value="Name 2">
<input class="item2" type="number" name="unit_price" id="unit_price2" value="200">
<input class="item2" type="number" name="qty" id="qty2" value="5">
<input class="item2" type="number" name="discount" id="discount2" value="10">
Then, for the javascript, because you are wanting to turn an array of items into a single object, this is a good candidate to use a reduce!
function aggrigateInputs(className) {
const elements = document.getElementsByClassName(className)
return elements.reduce((acc, elem) => {
acc[elem.name] = elem.value;
return acc;
}, {})
}
const item1 = aggrigateInputs('item1');
const item2 = aggrigateInputs('item2');
console.log(item1, item2);
I have multiple textboxes and I want to update a data-price attribute on blur.
If I change the value need to change specific 'data-price' attribute.
$(document).ready(function() {
$('#price').blur(function(){
$test=$(this).attr('data-price');
$test=$(this).val();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="price" class="default used_asset1" maxlength="8" placeholder="Amount" data-price="342" name="price" type="text" value="342">
<input id="price" class="default used_asset1" maxlength="8" placeholder="Amount" data-price="3" name="price" type="text" value="3">
<input id="price" class="default used_asset1" maxlength="8" placeholder="Amount" data-price="25" name="price" type="text" value="25">
<input id="price" class="default used_asset1" maxlength="8" placeholder="Amount" data-price="32" name="price" type="text" value="32">
Is it possible to update attribute value in jquery.What I did wrong in my code
Use price as class because element IDs should be unique within the entire document.
$(document).ready(function() {
$('.price').blur(function(){
//$test=$(this).attr('data-price');
//$test=$(this).val();
$(this).attr('data-price', $(this).val());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input class="price efault used_asset1" maxlength="8" placeholder="Amount" data-price="342" name="price" type="text" value="342">
<input class="price efault used_asset1" maxlength="8" placeholder="Amount" data-price="3" name="price" type="text" value="3">
<input class="price efault used_asset1" maxlength="8" placeholder="Amount" data-price="25" name="price" type="text" value="25">
<input class="price efault used_asset1" maxlength="8" placeholder="Amount" data-price="32" name="price" type="text" value="32">
You can't select an element by ID if the ID has been duplicated. It will work on the first one and ignore the rest. Selecting by class or element name will select all of them.
https://jsfiddle.net/5n71z2uq/
I'm selecting the inputs but you can put a class in and select VIA class.
$(document).ready(function() {
$('input').blur(function(){
$(this).attr('data-price', this.value);
});
});
Yeah you can. It's very easy, just try it.
$(document).ready(function(){
$('#price').blur(function(){
$(this).data('price', $(this).val());
});
});
I have an invoice which is not a table but inside a div in html are some input fields. These fields are being created dynamically by clicking on a button.
<li><input type="text" id="cost[]" name="unit[]" value="<?php echo $val->unit ; ?>"> </li>
<li><input type="text" id="qty[]" name="rate[]" value="<?php echo $val->rate ; ?>"> </li>
<li><input type="text" id="price[]" name="total[]" value="<?php echo $val->total ; ?>"> </li>
Now I want to multiply unit with rate and display it in the total field.
My Javascript is
window.onkeyup=function() {
var str = document.getElementById("cost[]").value;
var str1 = document.getElementById("qty[]").value;
var price = parseFloat(str*str1);
document.getElementById("price[]").value = price;
}
The javascript above works fine but it works only for the first row. For the rest of the rows below the first row, it does not work. I want the calculation for all the rows. I have seen some of the answers but none of them works in my case.
Any help is welcome.
What I observe from your code is that you might be using same ids for multiple items.
The "id" attribute assigns a name to an element. This name must be unique in a document.
Though we have a workaround like:
document.querySelectorAll("[id='someID']");
to select all elements with same "id"s, your HTML will be invalid.
And this is why we have "class" instead. A class is a group of elements.
Though I have used "name" attribute.
May be what you are looking for:
window.onkeyup=function() {
var items = document.querySelectorAll(".item");
var itemsArray = Array.prototype.slice.call(items,0);
var unit, rate, total, net = 0;
itemsArray.forEach(function(el){
unit = el.querySelector('input[name="unit[]"]').value;
rate = el.querySelector('input[name="rate[]"]').value;
total = unit * rate;
el.querySelector('input[name="total[]"]').value = total;
net+=total;
});
document.getElementById('net').value=net;
}
<div class='item'>
<li><input type="text" name="unit[]" value=""> </li>
<li><input type="text" name="rate[]" value=""> </li>
<li><input type="text" name="total[]" value=""> </li>
</div>
<br><br>
<div class='item'>
<li><input type="text" name="unit[]" value=""> </li>
<li><input type="text" name="rate[]" value=""> </li>
<li><input type="text" name="total[]" value=""> </li>
</div>
</br></br>
<li><input id='net' type="text" name="net[]" value=""> </li>
As I've stated before, It's not recommended to keep multiple elements with the same id on your HTML. But if you want to keep things that way, then you can make use of document.querySelectorAll and iterate over the elements to sum their value and store it in the total:
window.onkeyup=function() {
var costs = document.querySelectorAll("input[id='cost[]'");
var qtys = document.querySelectorAll("input[id='qty[]'");
var price = 0;
for (var i = 0; i < costs.length; i++){
price += +costs[i].value + +qtys[i].value;
}
document.getElementById("price[]").value = price;
}
<input type="text" id="cost[]" name="unit[]" value="2">
<input type="text" id="qty[]" name="rate[]" value="4">
<br>
<input type="text" id="cost[]" name="unit[]" value="2">
<input type="text" id="qty[]" name="rate[]" value="4">
<br>
<input type="text" id="cost[]" name="unit[]" value="2">
<input type="text" id="qty[]" name="rate[]" value="4">
<br>
<input type="text" id="cost[]" name="unit[]" value="2">
<input type="text" id="qty[]" name="rate[]" value="4">
<input type="text" id="price[]" name="total[]" value="">
var invoices = document.querySelectorAll('.invoice')
var handleChange = function (foo, bar, total) {
let str = +foo.value || 0
let str2 = +bar.value || 0
total.value = parseFloat(str*str2)
}
invoices.forEach(function(invoice) {
var foo = invoice.querySelector('input[name=foo]')
var bar = invoice.querySelector('input[name=bar]')
var total = invoice.querySelector('input[name=total]')
foo.addEventListener('keyup', function() {
handleChange(foo, bar, total)
})
bar.addEventListener('keyup', function() {
handleChange(foo, bar, total)
})
})
<div class="invoice">
<input type="text" name="foo">
<input type="text" name="bar">
<input type="text" name="total">
</div>
<div class="invoice">
<input type="text" name="foo" value="">
<input type="text" name="bar" value="">
<input type="text" name="total">
</div>
<div class="invoice">
<input type="text" name="foo">
<input type="text" name="bar">
<input type="text" name="total">
</div>
<div class="invoice">
<input type="text" name="foo">
<input type="text" name="bar">
<input type="text" name="total">
</div>
<div class="invoice">
<input type="text" name="foo">
<input type="text" name="bar">
<input type="text" name="total">
</div>
Notice how i prepended a + to the parse of str & str2 this operator turns any String number into a Number
I recommend you do this because when querying the value of a input[type=text] - it will give you the value represented as a String...
This is fine when multiplying e.g '1'*'2'// = 2...
But, if you want to ADD two numbers together, your sum will be interpreted as concatenation e.g '2'+'2' // = '22'
It may also be smart to default your values to 0 if a value is not provided or a Alphabetic or special character is put into the input e.g 'hello'*'2' // = NaN
try
var str = +foo.value || 0;
var str1 = +bar.value || 0;
var price = parseFloat(str*str1);
Alternatively, make your input type="number" this will limit the user to only be able to input numbers.
$("button").on("click",function(){
var $this=$(this);
var Per=$(".per").val();
$(".anuzau").each(function(){
var Val=$(this).val();
if($this.hasClass("zau"))
$(this).val((((Val/100)*Per)+parseInt(Val)).toFixed(2));
else if($this.hasClass("anu"))
$(this).val((parseInt(Val)-((Val/100)*Per)).toFixed(2));
});
});
.anuzau{width:200px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="anu">-</button> <input class="per" type="text" size="6" value="0">%
<button class="zau">+</button>
<br><br>
<input type="text" size="6" class="anuzau" name="name" value="38.5"><br>
<input type="text" size="6" class="anuzau" name="name" value="75"><br>
<input type="text" size="6" class="anuzau" name="name" value="100">
I wish to increments/decrements all values by classname (anu zau), can anyone share me the jquery method? I have tried many tutorials.
I am new here, if anything wrong, please correct me.
<button class="anu">-</button> <input type="text" size="6" value="">%
<button class="zau">+</button>
<br><br>
<td><input type="text" size="6" class="anu zau" name="name" id="id" value="50"></td><br>
<td><input type="text" size="6" class="anu zau" name="name" id="id" value="200"></td><br>
<td><input type="text" size="6" class="anu zau" name="name" id="id" value="530"></td>
$("button").on("click",function(){
var $this=$(this);
var Per=$(".per").val();
$(".anuzau").each(function(){
var Val=$(this).val();
if($this.hasClass("zau"))
$(this).val((((Val/100)*Per)+parseInt(Val)));
else if($this.hasClass("anu"))
$(this).val((parseInt(Val)-((Val/100)*Per)));
});
});
.anuzau{width:200px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="anu">-</button> <input class="per" type="text" size="6" value="0">%
<button class="zau">+</button>
<br><br>
<input type="text" size="6" class="anuzau" name="name" value="50"><br>
<input type="text" size="6" class="anuzau" name="name" value="200"><br>
<input type="text" size="6" class="anuzau" name="name" value="530">
This should get you started. Not clear what precision you are looking for (adjust decimal_points accordingly)
var decimal_points = 2
$('button').click(function(){
var pVal = $('#percent').val(),
percent = pVal && !isNaN(pVal) ? +pVal/100 : 0;
//make it negative if anu button clicked
if($(this).hasClass('anu')){
percent = 0-percent;
}
$('input.anu').val(function(_, val){
// make sure input has numeric value
if(!val || isNaN(val) ){
return val;
}else{
return (+val + (val * percent)).toFixed(decimal_points);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="anu">-</button> <input id="percent" type="number" size="6" value="">%
<button class="zau">+</button>
<br><br>
<td><input type="text" size="6" class="anu zau" name="name" id="id" value="50"></td><br>
<td><input type="text" size="6" class="anu zau" name="name" id="id" value="200"></td><br>
<td><input type="text" size="6" class="anu zau" name="name" id="id" value="530"></td>
I have a number of
<input type="text" name="price[]" value="100">
<input type="text" name="price[]" value="50">
<input type="text" name="price[]" value="10">
<input type="text" name="price[]" value="90">
I also have a input field
<input type="text" name="Add" value="">
I want
each price[] input field to have their own Addition Button next to it that will get the value from that specific price[] input field
add the value from the Add input field to it
update the value of that specific price[] input field in the end
How can I do that?
to iterate through the price[]-boxes for adding buttons right to them and set the value from price[] to the button, do it like this
<input type="text" name="price[]" value="100">
<input type="text" name="price[]" value="50">
<input type="text" name="price[]" value="10">
<input type="text" name="price[]" value="90">
<script type="text/javascript">
$(document).ready(function() {
$('input[name="price[]"]').each(function(i) {
$(this).after('<button class="additionButton" price="'+$(this).val()+'">'+$(this).val()+'</button>');
});
//click
$(".additionButton").on('click',function() {
//original price, set on load
alert($(this).attr('price'));
//price in the input-field before the button (could be changed, think this is the idea)
alert($(this).prev('input').val());
});
});
</script>
for the rest, i am not sure what you mean, "Add" has no value and you seriously want some kind of calculation? But try yourself, here was at least the iteration.