How to do calculation with inputs generated by foreach? - javascript

I have an foreach returning multiple items from mysql db. Each object is in an input field in my html.
I want to calculate 2 input values and display them in a third as a result.
It works when i have only 1 set of inputs (quantity * unit = result), but using foreach will assign each unit and result input the same class, therefore my js doesn't seem to work.
My target is to have a list of items from mysql generated with foreach and let the user define a quantity value, this would calculate the total.
But at the moment, when i change the qty value, it calculates with all input_price_unit inputs.
I have 3 inputs:
1 with class = input_itm_qty
1 with class = input_price_unit
1 with class = input_price_total
Below is my function:
$(".price_calc").keyup(function(){
var val1 = +$(".input_itm_qty").val();
var val2 = +$(".input_price_unit").val();
$(".input_price_total").val(val1*val2);
});

You could wrap (group) your elements into some common parents, say for example the class is .someParentClass than you could do like:
$(".price_calc").on("input", function(){
var $parentElement = $(this).closest(".someParentClass");
var val1 = +$parentElement.find(".input_itm_qty").val();
var val2 = +$parentElement.find(".input_price_unit").val();
$parentElement.find(".input_price_total").val(val1*val2);
}).trigger("input");
.someParentClass{border-bottom: 1px solid #999;}
[type=number]{text-align: right;}
[disabled] {background:0; border:0;}
<div class="someParentClass">
FOOS<br>
<input class="input_itm_qty price_calc" type=number value=1 min=0> QTY<br>
<input class=input_price_unit type=number disabled value=20> $<br>
<input class=input_price_total type=number disabled> TOTAL
</div>
<div class="someParentClass">
BARS<br>
<input class="input_itm_qty price_calc" type=number value=1 min=0> QTY<br>
<input class=input_price_unit type=number disabled value=35> $<br>
<input class=input_price_total type=number disabled> TOTAL
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Related

How to print the values in the same input text field using JS

I have created 5 input text boxes using HTML and made a button while clicking the button the values will print the result input text box. The first 4 fields are my inputs and the last text field is my output. unable to debug the issue. kindly find the code and help to find the issue.
function JS(){
var h=document.getElementById('h').value;
var w=document.getElementById('w').value;
var g=document.getElementById('g').value;
var t=document.getElementById('t').value;
var total =(h+w+g+t);
document.getElementById('result').innerHTML=total;
}
<h2> Calculator</h2>
<input type="text" placeholder="value1" id="h">
<input type="text" placeholder="value2"id="w">
<input type="text" placeholder="value3" id="g">
<input type="text" placeholder="value4" id="t">
<input type="text" placeholder="result" id="result">
<!--
<p
id="result">
</p>
-->
<button id="btn" onClick="JS()">Calculate</button>
There are two keys to resolving your issue:
Coerce your inputs to numbers, which I'm doing by adding a + in front of the value assignments. If you don't do this, your values may be treated like strings and concatenated rather than added like numbers.
Set the value of the input element, not the innerHTML. If you'd rather use a <p> element, which it appears you commented out in your sample code (and which I restored for completeness of my answer), consider using innerText.
See example here:
function JS() {
var h = +document.getElementById('h').value;
var w = +document.getElementById('w').value;
var g = +document.getElementById('g').value;
var t = +document.getElementById('t').value;
let p_result = document.getElementById('p_result');
var total = (h + w + g + t);
document.getElementById('result').value = total;
p_result.innerText = total;
}
<h2> Calculator</h2>
<input type="text" placeholder="value1" id="h">
<input type="text" placeholder="value2" id="w">
<input type="text" placeholder="value3" id="g">
<input type="text" placeholder="value4" id="t">
<input type="text" placeholder="result" id="result">
<br>
<p id="p_result" style="color:red;"></p>
<br>
<button id="btn" onClick="JS()">Calculate</button>
function JS(){
var h=document.getElementById('h').value;
var w=document.getElementById('w').value;
var g=document.getElementById('g').value;
var t=document.getElementById('t').value;
var total =(Number(h)+Number(w)+Number(g)+Number(t));
document.getElementById('result').value =total;
}
.value instead of .innerHTML
also, you should convert inputs values to number cause instead of making the sum will be as consider them string( for example if you type 1 , 2 , 3 , 4 without converting to number will be 1234 if you convert to number will be 10

How to fill input field value from javascript id value?

I am having difficulty in getting value from javascript id to the input field. I tried all the answers available on the platform but not worked. while I am getting the value of id="price_div" properly but not in input filed just where id is named. mean id="price_div" has a value when i apply it as like i got value here . but when i use i don't get value in value filed
<div class="title-calc">Approx. price</div>
<div class="price-total" id="price_div">
<input type="hidden" name="price" value=""> //Here i want to add price div value
<span class="currency">$</span><span class="price"></span>
as i understood, you get the value but you can't put this value as the input value. the solution is here, suppose your value is x:
document.getElementsByName("price")[0].value = x;
Give id to your input field and then append value through JavaScript
<div class="title-calc">Approx. price</div>
<div class="price-total" id="price_div">
<input type="hidden" name="price" id="name" value="">
<span class="currency">$</span><span class="price"></span>
<script>
var input_value = document.getElementById("price_div").value
document.getElementById("name").value = input_value
</script>
div has no value ... so to reach input use
var INP = document.getElementById("price_div").firstChild
or
var INP =document.querySelectorAll("#price_div [name=price]")[0]
then INP.value='smth'
use input which is hidden to show a value in span
var SPAN = INP.parent.lastChild;
INP.addEventListener('change',function(ev){SPAN.innerHTML=INP.value;});
this solved my error
var INP = document.getElementByClasses("span").firstChild

Multiple input save one input value

I have Input section like i want to pass this 3 value in one input value with onchange
<script type="text/javascript">
function updateInput($i){
$('updateval').val($i);
}
</script>
<input type="text" onchange="updateInput(this.value)" >
<input type="text" onchange="updateInput(this.value)" >
<input type="text" onchange="updateInput(this.value)" >
<input type="text" id="updateval" >
i want to show here the all 3 value and with a seperation
like value1:value2:value3
in my last input section
Give the 3 input id not name, eg v1,v2,v3
onchange jquery those 3 input value. $('#updateval').val( [ $('#v1').val(),$('#v2').val(),$('#v3').val()].join(':'));
You're missing the position of source input on your function.
Input without name not passed in form submitted, except you send itvia coding.
<input type="text" class='val' >
<input type="text" class='val' >
<input type="text" class='val' >
<input type="text" id="updateval" >
<script>
$(document).ready(function(){
$('.val').on('keyup',function(){
let out=''
$(".val").each(function() {
out+= $(this).val()+":";
});
$('#updateval').val(out);
})
})
</script>
fiddle
<script type="text/javascript">
function updateInput(){
var val1 = $('#value1').val();
var val2 = $('#value2').val();
var val3 = $('#value3').val();
var output = val1 + ':' + val2 + ':' + val3
$('#updateval').val(output);
}
</script>
<input id="value1" type="text" Onkeyup="updateInput(this.value)" >
<input id="value2" type="text" Onkeyup="updateInput(this.value)" >
<input id="value3" type="text" Onkeyup="updateInput(this.value)" >
<input type="text" id="updateval" value="">
Fiddle
Details commented in demo.
// Reference the first form on page
const form = document.forms[0];
/*
Register form to the input event (or change event with .onchange)
The input event will fire immediately after the user has entered any data
The change event will fire when the user has entered data then triggers a blur event by
focusing elsewhere.
*/
form.oninput = display;
/*
//A Pass Event Object
/*
B1 event.currentTarget is the tag registered to event (form)
B2 .elements.text is a collection of all the form controls [name=text] (inputs)
B3 brackets and spread operator convert collection into an array [...all input]
B4 .map() returns each input value into an array
*/
/*
//C Get output.all and assign its value to the new array then convert it into a string
delimited by colons
//D End function
*/
function display(event) {//A
let texts = [...event.currentTarget.elements.text].map(txt => txt.value);//B1-4
event.currentTarget.elements.all.value = texts.join(':');//C
return false;//D
}
:root {
font: 400 5vw/1.2 Consolas
}
input,
output {
display: block;
font: inherit
}
<form>
<input name='text'>
<input name='text'>
<input name='text'>
<output name='all'></output>
</form>

Change text in specific table cell by user input and Javascript

How can a change the content of a cell based on user input?
The user should be able to change both the cell and the text in that cell.
This is an example of the table I want to use (without td id):
<table border="1" id="tbl">
<tr><td>text</td><td>text</td><td>text</td></tr>
<tr><td>text</td><td>text</td><td>text</td></tr>
</table>
This is some input fields, I guess:
<label for="row">Row: </label>
<input type="number" id="row" value="1" />
<label for="col">Column: </label>
<input type="number" id="col" value="1" />
<label for="textOut">Tekst: </label>
<input type="text" id="tblText" name="text" value="Some text"/>
<button onclick="changeTable()">Change cell</button>
And this is where I get lost... I've searched the web for hours, and I've tried many different things, but I'm completely stuck. No need to say I'm really new to JavaScript...
var tbl = document.getElementById("tbl");
function changeTable () {
var row = document.getElementById("tbl").rows;
var col = row[0].cells;
col[0].innerHTML = document.getElementById("tblText").value;
}
You got pretty far already. Al you needed to do is get the target row and column, compensate for an array starting at 0, validate user input to be no less then 1 and no more then the size of columns and rows.
If you don't validate user input you can get errors if you enter a number below 1 or greater then the number of columns, therefore I used the Math.min and Math.max functions. Min 0 and Max size of columns/rows compensated for arrays starting at 0.
Alternatively you could pop up an alert if the user enters a value greater or smaller then allowed.
var tbl = document.getElementById("tbl");
function changeTable(){
var rowUserInput = parseInt(document.getElementById("row").value)-1; // user input compensated for arrays starting at 0
var colUserInput = parseInt(document.getElementById("col").value)-1; // user input compensated for arrays starting at 0
var row = document.getElementById("tbl").rows;
var targetRow = Math.min(Math.max(rowUserInput
, 0), // we want the maximum of user input and 0, so the value to use will never be less then 0
row.length - 1); // we want the minimum of user input and the number of rows compensated for arrays starting at 0, so we will never try to change a row higher then exists
var col = row[targetRow].cells;
var targetCol = Math.min(Math.max(colUserInput
, 0), // we want the maximum of user input and 0, so the value to use will never be less then 0
col.length - 1); // we want the minimum of user input and the number of columns compensated for arrays starting at 0, so we will never try to change a column higher then exists
if(rowUserInput !== targetRow) {
console.log('You tried to use a non existing row!');
}
if(colUserInput !== targetCol) {
console.log('You tried to use a non existing column!');
}
col[targetCol].innerHTML = document.getElementById("tblText").value;
}
<table border="1" id="tbl">
<tr><td>text row 1</td><td>text</td><td>text</td></tr>
<tr><td>text row 2</td><td>text</td><td>text</td></tr>
</table>
<label for="row">Row: </label>
<input type="number" id="row" value="1" />
<label for="col">Column: </label>
<input type="number" id="col" value="1" />
<label for="textOut">Tekst: </label>
<input type="text" id="tblText" name="text" value="Some text" />
<button onclick="changeTable()">Change cell</button>
var tbl = document.getElementById("tbl");
function changeTable () {
var row = document.getElementById("tbl").rows;
var r= document.getElementById("row").value
var c= document.getElementById("col").value
var col = row[r].cells;
col[c].innerHTML = document.getElementById("tblText").value;
}
You forgot to read the row and col number from input tag. Here I have declared two variable named r and c for row value and column value.
You simply need to get input row and col value and pass thier indexes.
var tbl = document.getElementById("tbl");
function changeTable(){
const rowId = document.getElementById("row").value;
const colId = document.getElementById("col").value;
var row = document.getElementById("tbl").rows;
var col = row[rowId - 1].cells;
col[colId - 1].innerHTML = document.getElementById("tblText").value;
}
<table border="1" id="tbl">
<tr><td>text</td><td>text</td><td>text</td></tr>
<tr><td>text</td><td>text</td><td>text</td></tr>
</table>
<label for="row">Row: </label>
<input type="number" id="row" value="1" />
<label for="col">Column: </label>
<input type="number" id="col" value="1" />
<label for="textOut">Tekst: </label>
<input type="text" id="tblText" name="text" value="Some text" />
<button onclick="changeTable()">Change cell</button>
Assuming you enter correct existing Row and Column numbers, your function changeTable should be
function changeTable(){
// Get all the rows of the table
var rows = document.getElementById("tbl").rows;
// Target row and col index
var targetRow = document.getElementById("row").value;
var targetCol = document.getElementById("col").value;
// Target row with all its cells
var targetRowCells = rows[targetRow].cells;
// Target row with the target col (target cell) changed with the new value
targetRowCells[targetCol].innerHTML = document.getElementById("tblText").value;
}

JQuery/JavaScript: Iterate through form fields, perform calculation, then submit

Right now my code is very "hard-coded" and repetitive. I'd like to know if there is a cleaner way to do the following. Ideally, I want to iterate through my forms fields with a loop and calculate the results with one statement, but I'm struggling to figure out how best to do so.
Summary: I have ten form fields, each with a distinct decimal value that a user may or may not supply. When the user hits submit, it should add the value in the input field with a value being displayed on the current HTML page, then insert into the DB.
First, I grab that value from the form input field and convert it into a number with two decimal places. I then grab the current total from the HTML and add the two numbers together. After that I inject that total back into the form input field so that it can be stored in $_POST and inserted into a database.
How can I make my code more DRY (ie, Don't Repeat Yourself)? Below are just two examples but they are exactly the same except for the element calls:
var subtotal = Number($("#housing").val());
subtotal = (subtotal).toFixed(2);
var currentTotal = $('#output-housing').html().replace("$", "");
var total = Number(subtotal) + Number(currentTotal);
$('#housing').val(total);
var subtotal = Number($("#utilities").val());
subtotal = (subtotal).toFixed(2);
var currentTotal = $('#output-utilities').html().replace("$", "");
var total = Number(subtotal) + Number(currentTotal);
$('#utilities').val(total);
I would like to iterate through my input fields like so, but I'm trying to figure out how I could display the logic inside:
var input = $('.form-expenses :input');
input.each(function() {
// Insert switch statement here?? Some other construct??
});
HTML: (Uses Bootstrap 3 classes)
FORM:
<form class="form-expenses form-horizontal" role="form" method="post" action="/profile/update">
<div class="form-group">
<label for="housing" class="control-label col-sm-3">Housing</label>
<div class="input-group input-group-lg col-sm-9">
<span class="input-group-addon">$</span>
<input type="text" class="form-control" name="housing" id="housing" />
</div>
</div>
<div class="form-group">
<label for="utilities" class="control-label col-sm-3">Utilities</label>
<div class="input-group input-group-lg col-sm-9">
<span class="input-group-addon">$</span>
<input type="text" class="form-control" name="utilities" id="utilities" />
</div>
</div>
...
<button class="btn btn-lg btn-primary btn-block" id="update-expenses" type="submit"> Update</button>
</form>
OUTPUT:
<tr>
<td>Housing</td>
<td id="output-housing">$<?php echo $total['housing']?></td>
</tr>
<tr>
<td>Utilities</td>
<td id="output-utilities">$<?php echo $total['utilities']?></td>
</tr>
Something like this should work. Assumes the same prefixing relationship of output/input ID's
$(function() {
$('form.form-expenses').submit(function() {
updateValues();
return false/* prevent submit for demo only*/
})
})
function updateValues(){
$('.form-expenses :input').not('#update-expenses').each(function(){
var $input=$(this), inputId=this.id;
var curr=$('#output-'+inputId).text().replace("$", "");
$input.val(function(i,val){
return (1*(val ||0) + 1*curr).toFixed(2);
})
});
}
DEMO
From a UI perspective, this seems very counter intuitive to change values that user just input.
To create ajax data object instead of updating the display values:
function getAjaxData(){
var ajaxData={}
$('.form-expenses :input').not('#update-expenses').each(function(){
var $input=$(this), inputId=this.id;
var curr=$('#output-'+inputId).text().replace("$", "");
ajaxData[this.name] =(1*(val ||0) + 1*curr).toFixed(2);
});
return ajaxData
}
/* in submit handler*/
$.post('path/to/server', getAjaxData(), function(response){/*do something with reponse*/})
"if I allow a user to add/remove fields, then this could get a bit sticky"
In that case, give your fields a class name. As long as that exists on added fields, they will all be calculated.
<input type="text" class="form-control calculate-me" name="housing" id="housing" />
And iterate though all, using their ids as a reference
$(".calculate-me").each(function(){
var ref=this.id;
var subtotal = Number($("#" + ref).val());
subtotal = (subtotal).toFixed(2);
var currentTotal = $('#output-' + ref).html().replace("$", "");
var total = Number(subtotal) + Number(currentTotal);
$('#' + ref).val(total);
});

Categories

Resources