Quiero calcular los días de una reserva para un sitio web de reservas. Quiero calcular el precio total (días * $ 100) automáticamente sin hacer clic en ningún botón para ejecutar la función, pero actualizar automáticamente sin actualizar la página.
function daysBetween(startDate, endDate) { var millisecondsPerDay = 1000 * 60 * 60 * 24; var startDateUTC = Date.UTC(startDate.getFullYear(), startDate.getMonth(), startDate.getDate()); var endDateUTC = Date.UTC(endDate.getFullYear(), endDate.getMonth(), endDate.getDate()); return Math.floor((endDateUTC - startDateUTC) / millisecondsPerDay); } document.getElementById("btn").addEventListener("click", function() { let startDate = new Date(document.getElementById("startdate").value); let endDate = new Date(document.getElementById("enddate").value); let output = document.getElementById("totalprice"); // Get how much days is between these dates let days = daysBetween(startDate, endDate); if (days) { output.classList.remove("text-danger"); output.innerHTML = `${days*100}€`; } else { /* if no valid date is entered */ output.classList.add("text-danger"); output.innerHTML = `Select valid dates`; } }, false); <section class="sec5">Check in</section> <section class="sec2"><input class="date" id="startdate" type="date" name="checkin" required=""></section> <section class="sec5">Check out</section> <section class="sec2"><input class="date" id="enddate" type="date" name="checkout" required=""></section> <p>Total price</p> <section class="sec3" id="totalprice" name="totalprice">--</section> <div id="btn">CALCULATE</div>La posible solución usa el evento de change a la última input (checkout input` para que la función se active cuando el usuario confirme el valor de un elemento.
El evento de cambio se activa para los elementos
<input><select>y<textarea>cuando el usuario confirma una alteración en el valor del elemento. A diferencia del evento de entrada, el evento de cambio no se activa necesariamente para cada modificación del valor de un elemento.
Además, agrego una declaración if para hacer que la función solo se ejecute cuando ambas input tengan valor.
function daysBetween(startDate, endDate) { var millisecondsPerDay = 1000 * 60 * 60 * 24; var startDateUTC = Date.UTC(startDate.getFullYear(), startDate.getMonth(), startDate.getDate()); var endDateUTC = Date.UTC(endDate.getFullYear(), endDate.getMonth(), endDate.getDate()); return Math.floor((endDateUTC - startDateUTC) / millisecondsPerDay); } document.getElementById("enddate").addEventListener("change",function(){ //Check if the value is existed if(document.getElementById("startdate").value) check() }); document.getElementById("startdate").addEventListener("change",function(){ //Check if the value is existed if(document.getElementById("enddate").value) check() }); function check() { let startDate = new Date(document.getElementById("startdate").value); let endDate = new Date(document.getElementById("enddate").value); let output = document.getElementById("totalprice"); // Get how much days is between these dates let days = daysBetween(startDate, endDate); if (days) { output.classList.remove("text-danger"); output.innerHTML = `${days*100}€`; } else { /* if no valid date is entered */ output.classList.add("text-danger"); output.innerHTML = `Select valid dates`; } } <section class="sec5">Check in</section> <section class="sec2"><input class="date" id="startdate" type="date" name="checkin" required=""></section> <section class="sec5">Check out</section> <section class="sec2"><input class="date" id="enddate" type="date" name="checkout" required=""></section> <p>Total price</p> <section class="sec3" id="totalprice" name="totalprice">--</section> <div id="btn">CLICK ME!</div>Use el evento de change pero aplíquelo a ambas entradas de esta manera:
function daysBetween(startDate, endDate) { var millisecondsPerDay = 1000 * 60 * 60 * 24; var startDateUTC = Date.UTC(startDate.getFullYear(), startDate.getMonth(), startDate.getDate()); var endDateUTC = Date.UTC(endDate.getFullYear(), endDate.getMonth(), endDate.getDate()); return Math.floor((endDateUTC - startDateUTC) / millisecondsPerDay); }; function recalculatePrice() { let startDate = new Date(document.getElementById("startdate").value); let endDate = new Date(document.getElementById("enddate").value); let output = document.getElementById("totalprice"); // Get how much days is between these dates let days = daysBetween(startDate, endDate); if (days) { output.classList.remove("text-danger"); output.innerHTML = `${days*100}€`; } else { /* if no valid date is entered */ output.classList.add("text-danger"); output.innerHTML = `Select valid dates`; } }; document.querySelector("#startdate").addEventListener("change", recalculatePrice, false); document.querySelector("#enddate").addEventListener("change",recalculatePrice , false); <section class="sec5">Check in</section> <section class="sec2"><input class="date" id="startdate" type="date" name="checkin" required=""></section> <section class="sec5">Check out</section> <section class="sec2"><input class="date" id="enddate" type="date" name="checkout" required=""></section> <p>Total price</p> <section class="sec3" id="totalprice" name="totalprice">--</section> <div id="btn">CLICK ME!</div>Solo agrega:
onchange="daysBetween()"En tu caso:
<section class="sec5">Check in</section> <section class="sec2"><input class="date" onchange="daysBetween()" id="startdate" type="date" name="checkin" required=""></section> <section class="sec5">Check out</section> <section class="sec2"><input class="date" onchange="daysBetween()" id="enddate" type="date" name="checkout" required=""></section> <p>Total price</p> <section class="sec3" id="totalprice" name="totalprice">--</section>