I've found this on google and gave it a go. But it seems as if its not doing anything. it isn't updating the price total area at all, nor is it adding or subtracting.
<script type="text/javascript">
function doMath() {
// Capture the entered values of two input boxes
var my_input1 = document.getElementsByName("case").value;
var my_input2 = document.getElementsByName("cpu").value;
var my_input3 = document.getElementsByName("cooling").value;
var my_input4 = document.getElementsByName("ram").value;
var my_input5 = document.getElementsByName("gpuchoice").value;
var my_input6 = document.getElementsByName("storage").value;
var my_input7 = document.getElementsByName("storage1").value;
var my_input8 = document.getElementsByName("storage2").value;
var my_input9 = document.getElementsByName("powersupchoice").value;
var my_input10 = document.getElementsByName("fans").value;
var my_input11 = document.getElementsByName("lighting").value;
var my_input12 = document.getElementsByName("sleeving").value;
var my_input13 = document.getElementsByName("peripherals").value;
var my_input14 = document.getElementsByName("headsets").value;
var my_input15 = document.getElementsByName("controllers").value;
var my_input16 = document.getElementsByName("wirelessadapter").value;
// Add them together and display
var sum = parseInt(my_input1) parseInt(my_input2) parseInt(my_input3) parseInt(my_input4) parseInt(my_input5) parseInt(my_input6) parseInt(my_input7) parseInt(my_input8) parseInt(my_input9) parseInt(my_input10) parseInt(my_input11) parseInt(my_input12) parseInt(my_input13) parseInt(my_input14) parseInt(my_input15) parseInt(my_input16);
document.getElementsByName("text2").value = sum;
document.getElementsByName("text2").innerHTML = sum;
}
</script>
the specific page im trying to get it to work on is: voidtechpcs.com/testbuild.php It's not pretty so be warned, I'm fairly new to this.
Any advice, or a better way of handling this perhaps?
CodePudding user response:
as @cheesyMan says your html is a mess and you are trying to brute for something that is better handled by finesse
i would aim for something more like this
const headsetData = { // preferably this would be read form a database or other not on page source
"none":{
display:"None",
price:0
},
"rzp7":{
display:"Razer BlackShark V2 Pro 7.1 Wireless ( $100.00)",
price:100
},
"hxc7":{
display:"HyperX Cloud II 7.1 Wireless ( $95.00)",
price:95
},
}
you could then populate from this list
const headsetselect = document.querySelector('select[name=headsets]')
for(const [key, {display} of Object.entries(headsetData)){
const opt = document.createElement("option");
opt.value = key;
opt.innerHTML = display;
headsetselect .appendChild(opt );
}
and then at the calculation stage you would do
const headsetselect = document.querySelector('select[name=headsets]')
total = headsetData[headsetselect.value].price
though if you follow best practice and id
s are unique per element then
document.getElementById("headset")
would be be better than a query selector
edit: you mention that you also wanted the text for an email
which can also be easilty accompliched like this
const product = headsetData[headsetselect.value]
text = `${product.display} ( ${product.price})`
CodePudding user response:
I write an answer as it's a bit too long for a comment.
There's a lot of mess both in your HTML code and in the way you try to select elements. You have a mix of <input>
and <select>
elements in your page, whose values you try to select and sum.
When you select <input>
elements via getElementsByName
, you select indeed a NodeList of elements (there are also some <h1>
inside!), so you have to narrow them to the ones you really need to get their value
.
The right selections for your elements would be:
var my_input1 = document.querySelector('[name=case]:checked').value;
var my_input2 = document.querySelector('[name=cpu]:checked').value;
var my_input3 = document.querySelector('[name=cooling]:checked').value;
var my_input4 = document.querySelector('[name=ram]:checked').value;
var my_input5 = document.querySelector('[name=gpuchoice]:checked').value;
var my_input6 = document.querySelector('[name=storage]:checked').value;
var my_input7 = document.querySelector('[name=storage1]').value;
var my_input8 = document.querySelector('[name=storage2]').value;
var my_input9 = document.querySelector('[name=powersupchoice]:checked').value;
var my_input10 = document.querySelector('[name=fans]:checked').value;
var my_input11 = document.querySelector('[name=lighting]:checked').value;
var my_input12 = document.querySelector('[name=sleeving]').value;
var my_input13 = document.querySelector('[name=peripherals]').value;
var my_input14 = document.querySelector('[name=headsets]').value;
var my_input15 = document.querySelector('[name=controllers]').value;
var my_input16 = document.querySelector('[name=wirelessadapter]').value;
Still too much cumbersome to be honest, but at least it selects the right elements.
But, also this way it won't work for your purposes. That's because sometimes your <input>
/<select>
elements have a value like value="45"
, some other times they have a value like value="Moroval Diamond Mesh Case"
; this way, they are not summable:
"45" "Moroval Diamond Mesh Case" // will yield the string "45Moroval Diamond Mesh Case"
That's the exact list of values you would get from my code above:
"45" // parseInt() -> 45
"Ryzen 5 3600 ( $0.00)" // parseInt() -> NaN
"Thermaltake TH120 RGB ( $0.00)" // parseInt() -> NaN
"Corsair Vengeance LPX 16 GB (2 x 8 GB) DDR4-3200 Memory ( $0.00)" // parseInt() -> NaN
"XFX Radeon RX 6500 XT 4 GB Speedster QICK 210" // parseInt() -> NaN
"Samsung 970 Evo Plus M2 NVME SSD 500 GB ( $0.00)" // parseInt() =-> NaN
"None" // parseInt() -> NaN
"None" // parseInt() -> NaN
"Corsair CX 650M 650 WATT BRONZE Power Supply ( $0.00)" // parseInt() -> NaN
"Artic P12 Non-RGB Case Fans x3 ( $0)" // parseInt() -> NaN
"No Lighting Selected" // parseInt() -> NaN
"None" // parseInt() -> NaN
undefined // parseInt() -> NaN
"None" // parseInt() -> NaN
"None" // parseInt() -> NaN
"No Wireless Adapter" // parseInt() -> NaN
The only number comes from the first selection. Others are strings or undefined
, so parseInt()
won't be a number but NaN
(Not a Number).
Edit (based on @MikeT comment):
It's better to always use numbers for value
attribute in this case. Something like (random numbers):
Consider that in your <select>
elements, each <option>
tag should always have a unique identifier as value
(to be sure to uniquely identify each option):
// select HTML element
<select name="headsets" id="headsets">
<option value="1">None</option>
<option value="2">Razer BlackShark V2 Pro 7.1 Wireless ( $100.00)</option>
<option value="3">HyperX Cloud II 7.1 Wireless ( $95.00)</option>
<option value="4">Corsair Void RGB Elite 7.1 Wireless ( $87.60)</option>
<option value="5">Logitech G935 DTS:X 7.1 Wireless ( $156.99)</option>
</select>
// hard-coded array of products to link selected value and price. probably a database-based solution is a better choice
const headsets = [
{ id: 1, description: 'None', price: 0 },
{ id: 2, description: 'Razer BlackShark V2 Pro 7.1 Wireless', price: 100 },
{ id: 3, description: 'HyperX Cloud II 7.1 Wireless', price: 95 },
{ id: 4, description: 'Corsair Void RGB Elite 7.1 Wireless', price: 87.6 },
{ id: 5, description: 'Logitech G935 DTS:X 7.1 Wireless', price: 156.99 },
];
// this is the price to sum
const selectedHeadsetPrice = headsets.find(item => item.id === document.getElementById('headsets').value).price;