I have this form:
<form>
<div role="group" aria-labelledby="info">
<p id="info"> Datos de clientes</p>
<label >Nombre
<input type="name" name="nombre" >
</label>
<label >Email
<input type="email" name="email" >
</label>
<label >Numero de personas
<input type="number" min="1" name="number" value="number">
</label>
</div>
<div role="group" aria-labelledby="destino-info">
<p id="destino-info">Destino:</p>
<label >
<input type="radio" name="destino" value="destino" onClick="changeFormula(1)" checked >
Cuidad</label>
<label >
<input type="radio" name="destino" value="mantaña" onClick="changeFormula(2)" > Montaña </label>
<label >
<input type="radio" name="destino" value="playa" onClick="changeFormula(3)" >Playa</label>
<button type="submit">Calcular tarifa</button></div>
</form>
<h3>El precio:</h3>
On submit, I need to calculate the total price depending on the number of people and type of holiday. For example, the price of the city is 100, the mountains - 130, and the beach - 150.
I don't understand how to change the cost depending on the selected radio button.
Here is what I tried, but now i feel lost:
const price =[
{cost:100},
{cost:130},
{cost:150}
];
function CalculateTotal(){
let numberOfGuests = document.getElementsByName("number").value;
let typeOfDestiny =document.getElementsByName("destino")
let total =numberOfGuests*typeOfDestiny;
}
CodePudding user response:
Try below code and add id="number" to Numero de personas field and change value="Cuidad" to Cuidad radio button.
const priceList = [{ destination: "Cuidad", cost: 100 },{ destination: "mantana", cost: 130 },{ destination: "playa", cost: 150 },];
const TOTAL_PRICE_HEADING = 'El precio:';
function calculateTarifa() {
const slectedDestination = document.querySelector("input[name='destino']:checked").value;
const idx = priceList.findIndex((place) => place.destination === slectedDestination);
if (idx >= 0) {
const numGuests = document.getElementById("numGuests").value;
const totalCost = priceList[idx].cost * (numGuests * 1);
updateTotalCost(totalCost);
}
}
function updateTotalCost(cost) {
const totalCostElement = document.querySelector('h3');
totalCostElement.innerText = `${TOTAL_PRICE_HEADING} ${cost}`;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<form>
<div role="group" aria-labelledby="info">
<p id="info">Datos de clientes</p>
<label >Nombre
<input type="name" name="nombre" />
</label>
<label >Email
<input type="email" name="email" />
</label>
<label >Numero de personas
<input type="number" min="1" id="numGuests" name="number" value="number" />
</label>
</div>
<div role="group" aria-labelledby="destino-info">
<p id="destino-info">Destino:</p>
<label >
<input type="radio" name="destino" value="Cuidad" checked />
Cuidad</label>
<label >
<input type="radio" name="destino" value="mantana" />
Montaña
</label>
<label >
<input type="radio" name="destino" value="playa" />Playa</label>
<button type="button" onclick="calculateTarifa()">
Calcular tarifa
</button>
</div>
</form>
<h3>El precio:</h3>
</body>
</html>
CodePudding user response:
Since your radio button values are the type of vacation, you will need to look-up the cost by that type. You should change your price
array into an object so that you can find the cost by type.
You can also throw in a currency formatter for good measure.
const form = document.forms.vacation;
const totalElement = document.querySelector('#total');
const currencyFormatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
});
const costLookup = {
'destino' : { cost: 100 },
'mantaña' : { cost: 130 },
'playa' : { cost: 150 }
};
function CalculateTotal(event) {
event.preventDefault();
const numberOfGuests = form.elements.number.value;
const typeOfDestiny = costLookup[form.elements.destino.value].cost;
const total = numberOfGuests * typeOfDestiny;
totalElement.textContent = currencyFormatter.format(total);
return false;
}
button[type="submit"] { display: block; }
.data-label { display: grid; grid-template-columns: 10em 1fr; }
#destino-info { display: inline-block; }
<form id="vacation" onSubmit="CalculateTotal(event)">
<div role="group" aria-labelledby="info">
<p id="info">Datos de clientes</p>
<label >Nombre
<input type="name" name="nombre" >
</label>
<label >Email
<input type="email" name="email" >
</label>
<label >Numero de personas
<input type="number" min="1" name="number" value="number">
</label>
</div>
<div role="group" aria-labelledby="destino-info">
<p id="destino-info">Destino:</p>
<label >
<input type="radio" name="destino" value="destino" checked >
Cuidad
</label>
<label >
<input type="radio" name="destino" value="mantaña">
Montaña
</label>
<label >
<input type="radio" name="destino" value="playa">
Playa
</label>
<button type="submit">Calcular tarifa</button></div>
</form>
<h3>El precio:</h3>
<div id="total"></div>
You could also use data attributes i.e. data-cost
instead of keeping an in-memory mapping of prices. Be aware that you will have to find the :checked
radio button to access the attribute.
const form = document.forms.vacation;
const totalElement = document.querySelector('#total');
const currencyFormatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
});
function CalculateTotal(event) {
event.preventDefault();
const numberOfGuests = form.elements.number.value;
const checked = form.querySelector('input[name="destino"]:checked');
const destinationCost = checked.getAttribute('data-cost');
const total = numberOfGuests * destinationCost;
totalElement.textContent = currencyFormatter.format(total);
return false;
}
button[type="submit"] { display: block; }
.data-label { display: grid; grid-template-columns: 10em 1fr; }
#destino-info { display: inline-block; }
<form id="vacation" onSubmit="CalculateTotal(event)">
<div role="group" aria-labelledby="info">
<p id="info">Datos de clientes</p>
<label >Nombre
<input type="name" name="nombre" >
</label>
<label >Email
<input type="email" name="email" >
</label>
<label >Numero de personas
<input type="number" min="1" name="number" value="number">
</label>
</div>
<div role="group" aria-labelledby="destino-info">
<p id="destino-info">Destino:</p>
<label >
<input type="radio" name="destino" value="destino" data-cost="100" checked >
Cuidad
</label>
<label >
<input type="radio" name="destino" value="mantaña" data-cost="130">
Montaña
</label>
<label >
<input type="radio" name="destino" value="playa" data-cost="150">
Playa
</label>
<button type="submit">Calcular tarifa</button></div>
</form>
<h3>El precio:</h3>
<div id="total"></div>
CodePudding user response:
Here's another (hopefully easier) way of looking at it. You can store the cost of these things directly in the HTML element as a dataset property. Then apply a click listener that will calculate the total each time one of them is clicked.
let total = 0;
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('[data-cost]').forEach(r => {
r.addEventListener('click', e => runCalc(e));
if (r.checked) runCalc({target: r});
})
document.querySelector('#form').addEventListener('submit', e => {
e.preventDefault(); // don't submit
let chosendest = document.querySelector('[data-cost]:checked');
console.log(`the selected destination is ${chosendest.value} for $${chosendest.dataset.cost}`);
})
})
const runCalc = e => {
let total = e.target.dataset.cost;
let loc = e.target.value
document.querySelector('#total').innerHTML = `<h2>Going to the ${loc} will cost ${total}</h2>`;
}
<form id="form">
<div role="group" aria-labelledby="destino-info">
<p id="destino-info">Destino:</p>
<label >
<input type="radio" name="destino" value="destino" data-cost="100" checked >
Cuidad</label>
<label >
<input type="radio" name="destino" value="mantaña" data-cost="120" > Montaña </label>
<label >
<input type="radio" name="destino" value="playa" data-cost="130" >Playa</label>
</div>
<button type="submit">Calcular tarifa</button>
</form>
<div id='total'></div>