The answer is supposed to be a 2 digit number but the answer isnt even close to 2 digits
CodePudding user response:
.value belongs to the DOM API and such API does have types. The value property is of type DOMString.
Therefore, the problem is when you are adding all those values, it does a string concatenations rather than arithmetic addition. You need to parse it to number before adding.
const getValue = (id) => document.querySelector(`#${id}`).value;
const getAvg = () => {
const sub1 = getValue('subject1');
const sub2 = getValue('subject2');
const sub3 = getValue('subject3');
const sub4 = getValue('subject4');
const sub5 = getValue('subject5');
const avg = (sub1 sub2 sub3 sub4 sub5)/5;
alert(avg)
}
<input type='number' id='subject1' />
<input type='number' id='subject2' />
<input type='number' id='subject3' />
<input type='number' id='subject4' />
<input type='number' id='subject5' />
<button onClick='getAvg()'>CLICK ME</button>
CodePudding user response:
calculate on click
You'll need to parse the string values as numbers. I would suggest using a <form>
with an id
attribute so you can look up the form directly. Once you have a form reference, you can access all of the child input
, output
, and button
elements by their name
attribute.
const f = document.forms.marks
function calculate(sub1, sub2, sub3, sub4, sub5) {
return (sub1 sub2 sub3 sub4 sub5) / 5
}
f.calculate.addEventListener("click", event => {
const sub1 = Number.parseFloat(f.subject1.value) // <- parse!
const sub2 = Number.parseFloat(f.subject2.value)
const sub3 = Number.parseFloat(f.subject3.value)
const sub4 = Number.parseFloat(f.subject4.value)
const sub5 = Number.parseFloat(f.subject5.value)
f.total.value = calculate(sub1, sub2, sub3, sub4, sub5).toFixed(2)
})
input, output, button {
display: block;
}
<h3>Enter your marks</h3>
<form id="marks">
<input name="subject1" />
<input name="subject2" />
<input name="subject3" />
<input name="subject4" />
<input name="subject5" />
<output name="total"></output>
<button type="button" name="calculate">Calculate</button>
</form>
real-time calculate
Can we show the total score in real-time? How do we handle non-numeric inputs? How do ensure the input is between 0 and 100? What if we wanted more than five (5) subjects? Relying solely upon the DOM API can make it hard to get them right.
App preview |
---|
I share this as a teaser for React as it demonstrates how much is possible with so little code. Run the snippet below to see a dynamic form which handles errant input and calculates the total score as the user is typing -
function parseMark(value) {
const n = Number.parseFloat(value)
return Number.isNaN(n) ? 0 : Math.max(0, Math.min(100, n))
}
const updateArray = (arr, index, newvalue) =>
[...arr.slice(0, index), newvalue, ...arr.slice(index 1)]
const average = (nums) =>
nums.reduce((sum, num) => sum num, 0) / nums.length
function App() {
const [marks, setMarks] = React.useState([0])
const addMark = event =>
setMarks([...marks, 0])
const updateMark = index => event =>
setMarks(updateArray(marks, index, parseMark(event.target.value)))
return <div>
<h3>Enter your marks</h3>
<form>
{marks.map((mark, index) =>
<input key={index} value={mark} onChange={updateMark(index)} />
)}
Score: {average(marks).toFixed(2)}
<button type="button" onClick={addMark}>Add Subject</button>
</form>
</div>
}
ReactDOM.render(<App />, document.querySelector("#app"))
input, button {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>