Reputation: 101
Im trying to create a cost calculator script. It basically shows if the manual input is for example 10$ and if you choose week, month or year it multiples with 52 for week, 12 for month and 1 for year so it shows the cost total in year.
In the code snippet there are 2 variables for a house and car. For house it works fine and thats what I could do so far. I also need to add more fields like a car in example. And I want to be able to fill the cost for house and car and more fields and when I hit calculate button, it should be showing all the costs like house cost + car cost + other fields..
so far I could only make it work for the house, if you fill the car field it doesn't add in the total, how can I make it work and add more fields if I want and they should be also working.
var btn = document.querySelector('#calculate');
btn.addEventListener('click', function () {
var num1 = Number(document.querySelector('#num1').value),
rlt = document.querySelector('p.answer');
var method = document.querySelector('option[name="method"]:checked').value;
var answer = 0;
if ('week' === method) {
answer = num1 * (52);
} else if ('month' === method) {
answer = num1 * (12);
} else if ('year' === method) {
answer = num1;
}
rlt.innerHTML = answer;
});
<div class="container">
<div class="input-control">
<label style="Float:left;" for="num1">🏠
<input type="text" id="num1" autofocus>
$</label>
<label style="Float:left;" for="dropdown">
<select>
<option name="method" id="method_week" value="week">Week</option>
<option name="method" id="method_month" value="month">Month</option>
<option name="method" id="method_year" value="year">Year</option>
</select>
</label>
<div style="clear:both;"></div>
</div>
<div class="input-control">
<label style="Float:left;" for="num2">🚗
<input type="text" id="num2" autofocus>
$</label>
<label style="Float:left;" for="dropdown">
<select>
<option name="method" id="method_week" value="week">Week</option>
<option name="method" id="method_month" value="month">Month</option>
<option name="method" id="method_year" value="year">Year</option>
</select>
</label>
<div style="clear:both;"></div>
</div>
<div class="input-control button">
<button id="calculate">Calculate</button>
</div>
</div>
<div class="container result">
Answer
<p class="answer">0</p>
</div>
Upvotes: 0
Views: 69
Reputation: 17019
You can give each field
you need to calculate a class for example calc-container
and use querySelectorAll
to get them, and use reduce
method to accumulate the values of fields, and on each iteration get the value of it's select
and input
elements and multiply and then add it to the reduce
accumulator.
With this way, you can calculate any number of fields with any code duplication.
var btn = document.querySelector('#calculate');
const calcContainer = document.querySelectorAll('.calc-container');
const answerElement = document.querySelector('.answer');
const getPeriodValue = (num, method) => {
if ('week' === method) {
return num * 52;
} else if ('month' === method) {
return num * 12;
} else {
return num;
}
}
btn.addEventListener('click', function() {
const answer = [...calcContainer].reduce((acc, inputControl) => {
const period = inputControl.querySelector('select').value;
const number = inputControl.querySelector('input').value;
console.log(period, number)
return acc + getPeriodValue(number, period)
}, 0)
answerElement.innerHTML = answer;
});
<div class="container">
<div class="input-control calc-container">
<label style="Float:left;" for="num1">🏠
<input type="text" id="num1" autofocus>
$</label>
<label style="Float:left;" for="dropdown">
<select>
<option name="method" id="method_week" value="week">Week</option>
<option name="method" id="method_month" value="month">Month</option>
<option name="method" id="method_year" value="year">Year</option>
</select>
</label>
<div style="clear:both;"></div>
</div>
<div class="input-control calc-container">
<label style="Float:left;" for="num2">🚗
<input type="text" id="num2" autofocus>
$</label>
<label style="Float:left;" for="dropdown">
<select>
<option name="method" id="method_week" value="week">Week</option>
<option name="method" id="method_month" value="month">Month</option>
<option name="method" id="method_year" value="year">Year</option>
</select>
</label>
<div style="clear:both;"></div>
</div>
<div class="input-control button">
<button id="calculate">Calculate</button>
</div>
</div>
<div class="container result">
Answer
<p class="answer">0</p>
</div>
Upvotes: 1
Reputation: 8546
In your code, you are not getting the value of the second input, only from the first. Besides getting the input number, you will also have to get the value of the select tag of the car field.
In order to be able to differentiate between the select from the house and the car, I suggest you to add a distinct id
attribute to each select element, so you can get each on the query select.
Something like this:
var btn = document.querySelector('#calculate');
btn.addEventListener('click', function() {
var answer = 0;
var num1 = Number(document.querySelector('#num1').value);
var method1 = document.querySelector('#select1 > option[name="method"]:checked').value;
if ('week' === method1) {
answer += num1 * (52);
} else if ('month' === method1) {
answer += num1 * (12);
} else if ('year' === method1) {
answer += num1;
}
var num2 = Number(document.querySelector('#num2').value);
var method2 = document.querySelector('#select2 > option[name="method"]:checked').value;
if ('week' === method2) {
answer += num2 * (52);
} else if ('month' === method2) {
answer += num2 * (12);
} else if ('year' === method2) {
answer += num2;
}
rlt = document.querySelector('p.answer');
rlt.innerHTML = answer;
});
<div class="container">
<div class="input-control">
<label style="Float:left;" for="num1">
🏠<input type="text" id="num1" autofocus>$
</label>
<label style="Float:left;" for="dropdown">
<select id="select1">
<option name="method" id="method_week" value="week">Week</option>
<option name="method" id="method_month" value="month">Month</option>
<option name="method" id="method_year" value="year">Year</option>
</select>
</label>
<div style="clear:both;"></div>
</div>
<div class="input-control">
<label style="Float:left;" for="num2">
🚗<input type="text" id="num2" autofocus>$
</label>
<label style="Float:left;" for="dropdown">
<select id="select2">
<option name="method" id="method_week" value="week">Week</option>
<option name="method" id="method_month" value="month">Month</option>
<option name="method" id="method_year" value="year">Year</option>
</select>
</label>
<div style="clear:both;"></div>
</div>
<div class="input-control button">
<button id="calculate">Calculate</button>
</div>
</div>
<div class="container result">
Answer<p class="answer">0</p>
</div>
If the number of inputs for calculation will keep growing, you'd better extract the calculation logic into a separate, reusable function.
Upvotes: 1