-
Live Field Calculations
An image is worth a thousand words so:
http://funkysoulrebels.com/calc.gif
I basically want to have the user input the first two fields and have the last two get automagically calculated.
Field_3 = Field_1 - Field_2
Field_4 = (Field_1 ÷ Field_2) - 100
I've seen tons of examples using simple sums on text fields, but no idea where to start on something like this.
Any ideas?
-
I think your formulas are wrong so I modified them. I think the form should display the following:
1000:1500:500:33.3333
In any case, here's the code.
Code:
<form>
<input type="text" id="cost" />
<input type="text" id="charge" />
<input type="text" id="profit" />
<input type="text" id="percent" />
</form>
<script type="text/javascript">
function addEvent(els, type, func) {
if(!(els instanceof Array)) els = [els];
for(var i=0, n=els.length; i<n; ++i) {
if(els[i].addEventListener) els[i].addEventListener(type, func, false);
else els[i].attachEvent("on"+type, func);
}
}
String.prototype.trim = function() {
return this.replace(/^\s+/, "").replace(/\s+$/, "");
};
var cost = document.getElementById("cost");
var charge = document.getElementById("charge");
var profit = document.getElementById("profit");
var percent = document.getElementById("percent");
addEvent(
[cost, charge],
"keyup",
function(e) {
var vcost = cost.value.trim();
var vcharge = charge.value.trim()
var ncost = vcost*1;
var ncharge = vcharge*1;
if(vcost=="" || vcharge=="" || isNaN(ncost) || isNaN(ncharge)) {
profit.value = percent.value = "";
return;
}
profit.value = ncharge - ncost;
percent.value = (ncharge - ncost) * 100 / ncharge;
}
);
</script>
-
Wow.. you certainly write some lovely code there. So clear and easy to follow!
It works a charm, although now just out of curiosity I wonder if I can extend it so that typing in a percentage will populate the profit and charge fields, and then after that maybe even get the profit field to affect the others. I can do each of them by itself no problem, but tend to trip over myself when trying to combine the functions. Still trying to wrap my head around how JS deals with arrays.
Anyways, thank you muchly for the assist :)
-
If you do that, you will have to create a new event handler that consists of the %profit as the trigger. Aka, you will need a separate addEvent(a,b,c) function.
Remember, in order for what you want to do to work, you will either need to have the "Our Cost" field or the "What We Charge" field filled out in addition to the %profit.
-
Got it!
Code:
addEvent(
[cost, percent],
"keyup",
function(f) {
var vcost = cost.value.trim();
var vpercent = percent.value.trim();
var ncost = vcost*1;
var npercent = vpercent*1;
if(vcost=="" || vpercent=="" || isNaN(ncost) || isNaN(npercent)) {
profit.value = charge.value = "";
return;
}
profit.value = (ncost / 100 * npercent).toFixed(2);
charge.value = (ncost + (ncost / 100 * npercent)).toFixed(2);
}
);
You totally rock dude!
-
Actually, now that this is working, I have one last question.
At some point I will need to have multiple rows of these fields and I'm wondering how I can make this code more dynamic..IOW somehow pass the id's I want to use as arguments to functions...or something like that.
Just imagine me trying to use the above code on something like this:
Code:
<form>
<input type="text" id="cost_ac1500" />
<input type="text" id="charge_ac2500" />
<input type="text" id="profit_ac5000" />
<input type="text" id="percent_ac10000" /><br />
<input type="text" id="cost_df2500" />
<input type="text" id="charge_df5000" />
<input type="text" id="profit_df15000" />
<input type="text" id="percent_df20000" /><br />
<input type="text" id="cost_ry2500" />
<input type="text" id="charge_ry4000" />
<input type="text" id="profit_ry12000" />
<input type="text" id="percent_ry16000" /><br />
</form>
-
Woops!
After testing this out thoroughly its not working just yet. Im still stepping on my own toes it seems and the calculations are not accurate when I add multiple events.
Gonna sleep on this one and hack some more in the morning.
Edit: I lied. Stayed up a bit and fixed it. Now just have to make this modular and its a go.
-
If you can guarantee that the input tags come as groups of four and contains no other input tags then you could do something like this:
Code:
<form id="form1">
<input type="text" />
<input type="text" />
<input type="text" />
<input type="text" /><br />
<input type="text" />
<input type="text" />
<input type="text" />
<input type="text" />
</form>
<script type="text/javascript">
function addEvent(els, type, func) {
if(!(els instanceof Array)) els = [els];
for(var i=0, n=els.length; i<n; ++i) {
if(els[i].addEventListener) els[i].addEventListener(type, func, false);
else els[i].attachEvent("on"+type, func);
}
}
String.prototype.trim = function() {
return this.replace(/^\s+/, "").replace(/\s+$/, "");
};
var fields = document.getElementById("form1").getElementsByTagName("input");
for(var i=0, n=fields.length; i<n; i+=4) {
addEvent(
[fields[i], fields[i+1]],
"keyup",
(function(i) {
return function(e) {
var vcost = fields[i].value.trim();
var vcharge = fields[i+1].value.trim()
var ncost = vcost*1;
var ncharge = vcharge*1;
if(vcost=="" || vcharge=="" || isNaN(ncost) || isNaN(ncharge)) {
fields[i+2].value = fields[i+3].value = "";
return;
}
fields[i+2].value = ncharge - ncost;
fields[i+3].value = (ncharge - ncost) * 100 / ncharge;
};
})(i)
);
}
</script>
I admit, this is a bit grungy, but I don't have time to create to create prettier code.
-
My never being one to worry too much about neat code:
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
.calc, .calc table {
border-collapse:collapse;
margin:0;
}
.calc th {
font:bold 70% arial, sans-serif;
padding:.5em 0;
color:black;
text-align:left;
background-color:#c5c8b2;
text-indent:.5em;
}
.calc td {
background-color:#eceddf;
font:75% arial, sans-serif;
padding:.5em .5ex;
color:#8a8b7e;
}
.calc input {
width:7em;
}
</style>
<script type="text/javascript">
function tot(t){
var f=t.form.elements, e=['oc','ww'];
for (var i = 0; i < e.length; i++)
if(!f[e[i]].value||isNaN(f[e[i]].value-0))
return;
var m=f.ww.value-0, b=f.oc.value-0;
f.op.value=m-b;
f.pp.value=Math.round(((m-b)/b)*100);
}
</script>
</head>
<body>
<form class="calc" action="javascript:void(0)" onsubmit="return false;">
<table>
<tr>
<th>Our Cost</th><th>What We Charge</th><th>Our Profit</th><th>% Profit</th>
</tr>
<tr>
<td><input type="text" name="oc" onkeyup="tot(this);" onmouseover="tot(this);" onmouseout="tot(this);"></td>
<td><input type="text" name="ww" onkeyup="tot(this);" onmouseover="tot(this);" onmouseout="tot(this);"></td>
<td><input type="text" name="op" readonly></td>
<td>% <input type="text" name="pp" readonly></td>
</tr>
</table>
</form>
<form class="calc" action="javascript:void(0)" onsubmit="return false;">
<table>
<tr>
<th>Our Cost</th><th>What We Charge</th><th>Our Profit</th><th>% Profit</th>
</tr>
<tr>
<td><input type="text" name="oc" onkeyup="tot(this);" onmouseover="tot(this);" onmouseout="tot(this);"></td>
<td><input type="text" name="ww" onkeyup="tot(this);" onmouseover="tot(this);" onmouseout="tot(this);"></td>
<td><input type="text" name="op" readonly></td>
<td>% <input type="text" name="pp" readonly></td>
</tr>
</table>
</form>
</body>
</html>
-
I meant better code . . . not neater code. :D