I have a javascript that calculates the percentage from two fields (retail and network) and then dumps that percentage into another field (markup).
As I am relatively new to the world of JS I have ended up reusing the code for several rows of fields. This goes against DRY and KISS principles so I was wondering if you could give me some input on how to optimise my code so that it can handle any two fields and then dump a value to a third field.
Here is a screenshot of my form segment that is using it.
Here is my code I am using, I have had to reuse it four times and place the code in four functions eg (percentage1, percentage2, percentage3, percentage4) each one of these functions deals with a row of fields show in the screenshot.
function percentage1()
{
//the dividee
x = document.getElementById('tariff_data');
//the divider
y = document.getElementById('network_data');
//if the first value is lower than the second, append a "-" sign
if (x.value < y.value)
{
z = "-"+(x.value/y.value)*100;
document.getElementById('markup_data').value = z;
}
//not a negative percentage
else
{
z = (x.value/y.value)*100;
document.getElementById('markup_data').value = z;
}
}
function percentage2()
{
//the dividee
x = document.getElementById('tariff_rental');
//the divider
y = document.getElementById('network_rental');
//if the first value is lower than the second, append a "-" sign
if (x.value < y.value)
{
z = "-"+(x.value/y.value)*100;
document.getElementById('markup_rental').value = z;
}
//not a negative percentage
else
{
z = (x.value/y.value)*100;
document.getElementById('markup_data').value = z;
}
}
etc etc....
These functions are called using the onchange HTML attribute
Also when I divide by a decimal number it gives the wrong value, any Ideas how to make it calculate the correct percentage of a decimal number?
My code also gives out these strange outputs:
NaN , Infinity
Thanks
Rather than optimization, let's focus on correctness first =)
Note that the HTMLInputElement.value
property has type "string", so your arithmetic operators are doing implicit type conversion which means you are likely often doing string concatenation instead of the numeric operations you expect.
I strongly recommend explicitly converting them to numbers first and checking for invalid input, also, don't forget to declare your variables first using var
so they don't potentially clobber globals, eg:
var x = Number(document.getElementById('tariff_data'));
var y = Number(document.getElementById('network_data'));
if (!isFinite(x) || !isFinite(y)) {
// Handle non-numerical input...
}
You can also use the parseFloat
function if you prefer, eg:
var x = parseFloat(document.getElementById('tariff_data'), 10);
I highly recommend doing some formal learning about the JavaScript language; it is full of pitfalls but if you stick to the "good parts" you can save yourself a lot of hassle and headache.
With regard to DRYing your code out; remember that you can:
In your case, you've got all your multiplication code repeated. While trying to fix the string vs. number problems maerics has already mentioned, you could do something like this:
// We're assuming 'dividee' and 'divider' are numbers.
function calculatePercentage(dividee, divider) {
var result;
// Regardless of the positive/negative result of the calculation,
// get the positive result using Math.abs().
result = Math.abs((dividee.value / divider.value) * 100);
// If the result was going to be negative...
if (dividee.value < divider.value) {
// Convert our result to negative.
result = result * -1;
}
// Return our result.
return result;
}
Then, in your percentage functions, you can just call this code like so:
function percentage1() {
var tariff, network, markup;
tariff = parseFloat(document.getElementById('tariff_data').value, 10);
network = parseFloat(document.getElementById('network_data').value, 10);
markup = document.getElementById('markup_data');
markup.value = calculatePercentage(tariff, network);
}
Obviously, you could take this further, and create a function which takes in the IDs, extracts the values from the elements etc., but you should try and build that yourself based on these tips.
Maerics also makes a very good point which you should take note of; learn more about the Good Parts of JavaScript. Douglas Crockford's book is excellent, and should be read and understood by all JS developers, IMHO.
Hope this helps you clean your code up!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.