JS time calculation add and set value - javascript

I'm making a page to easily calculate when I could go home from work. The page should set a start date when loaded. That way I don't have to know when I started working and just open my browser. Then by clicking one of the buttons it should just add some hours.
The example is one of the many things I've tried already. But this one is close I think. Any suggestions are welcome. I didn't include jquery because of the small scale this has.
function reset() {
var date = new Date();
var hour = date.getHours(),
min = date.getMinutes();
hour = (hour < 10 ? "0" : "") + hour;
min = (min < 10 ? "0" : "") + min;
var timestamp = hour + ":" + min;
document.getElementById("start_time").value = timestamp;
}
function add_time_76() {
var start = document.getElementById("start_time").value;
document.getElementById("end_time").value = start + 7, 6;
}
function getTotal() {
var start = document.getElementById("start_time").value;
var end = document.getElementById("end_time").value;
document.getElementById("total").value = end - start;
}
<body onload="reset()">
<p>Start time: <input name="start_time" type="time" /></p>
<p>Time to go home: <input name="end_time" type="time" /></p>
<p>Total hours: <input type="text" name="total" readonly></p>
<button onclick="add_time_76()">Add 7,6h</button>
<button onclick="add_time_8()">Add 8h</button>
<br><br>
<button onclick="getTotal()">Calculate Total</button>
<br><br>
<button onclick="reset()">Reset</button>
</body>
The time fields aren't getting populated when I want them to be.

Just add a id to your inputs.
<p>Start time: <input id="start_time" name="start_time" type="time" /></p>
<p>Time to go home: <input id="end_time" name="end_time" type="time" /></p>
<p>Total hours: <input id="total" type="text" name="total" readonly></p>

Related

Reset function in JS keeps reloading page

I have a reset function in my codes that is keeping my form on a reloading loop.
When I click on my Calculate Button, the divtext that I am trying to display just "Blink" and it will go off.
I only want it to reset when reset button is clicked though. Don't know where it went wrong. Here are my codes.
function calculateDate() {
var startDate = document.getElementById("startDate").value;
var endDate = document.getElementById("endDate").value;
var dvtextless60 = document.getElementById("dvtextless60");
var dvtext61182 = document.getElementById("dvtext61182");
var dvtextmore183 = document.getElementById("dvtextmore183");
var Difference_In_Time = new Date(endDate).getTime() - new Date(startDate).getTime();
var Difference_In_Days = Difference_In_Time / (1000 * 3600 * 24);
if (Difference_In_Days < 60){
document.getElementById("dvtextless60").style.display = "block";
} else if (Difference_In_Days > 60 && Difference_In_Days <= 182){
document.getElementById("dvtext61182").style.display = "block";
} else {
document.getElementById("dvtextmore183").style.display = "block";
}
document.getElementById("daysCalculator").innerHTML = greeting;
}
function resetForm(){
document.getElementById('rCalculator').reset();
}
<form id="rCalculator">
<pre>
Enter Start Date: <input type="date" name="startDate" id="startDate"/><br>
Enter End Date: <input type="date" name="endDate" id="endDate"/><br>
Total Days : <span id="daysCalculator"></span>
<div id="dvtextless60" style="display:none">
<span style="font-size:18px"><b>Too Short</b></span>
<br>
</div>
<div id="dvtext61182" style="display:none">
<span style="font-size:18px"><b>Almost There</b></span>
</div>
<div id="dvtextmore183" style="display:none">
<span style="font-size:18px"><b>Too Long</b></span>
</div>
<button id="calculate" onclick="calculateDate();">Calculate</button> <button id="reset" onclick="resetForm();">Reset</button>
</pre>
You can solve this adding a type="button" to your reset button.
Considering the fact that you are using html form
I suggest you to edit your button with <type="submit"> and <type="reset">
and you can remove the button onClick and use form onsubmit={}
<form id="rCalculator" onsubmit="calculateDate()">
Enter Start Date: <input type="date" name="startDate" id="startDate"/><br>
Enter End Date: <input type="date" name="endDate" id="endDate"/><br>
<button id="calculate" type="submit">Calculate</button>
<button id="reset" type="reset">Reset</button>
</form>
Have an event.preventDefault() method in your calculate function. This way you can eliminate resetForm() function.

how to implement multiple countdowns on the same DOM element

I have a DOM element, that contains values (milliseconds) from my database, and I want to implement a countdown for the values. For example, I can have 4 product deals in a section, with different duration in milliseconds, and i want to dynamically create different countdowns(HH:mm:ss) for each deal according to its duration.
Currently, the duration values (milliseconds) are stored in a hidden input field for each deal in the section.
<input type="hidden" name="" id='duration' value="{{this.deals.duration}}">
What i tried (it works fine for only one product deal). I used moment.js for the duration. and also for the countdown here:
<script type="text/javascript">
$(document).ready(function(){
console.log($('#duration').val());
var interval = 1000;
var durations = $('#duration').val();
setInterval(function(){
durations = moment.duration(durations - interval, 'milliseconds');
// console.log(durations);
$('#countdown').text(durations.hours() + ":" + durations.minutes() + ":" + durations.seconds())
}, interval);
})
</script>
Thanks very much :)
To add another answer to this question...
No dependencies (jQuery,Moment.js) and only for 24 hour duration (days,months,years are not calculated).
function countDown(elClass) {
let labels = document.querySelectorAll(elClass);
let now = Date.now();
labels.forEach((label,key) => {
let duration = document.getElementById(label.getAttribute('for')).value;
if(duration <= 86400000) {
let futureDate = now + parseInt(duration);
let counterInterval = setInterval(() => {
let diff = futureDate - Date.now();
if(diff <= 0) {
clearInterval(counterInterval);
return;
}
if(diff > 0) {
let milliseconds = diff%1000;
let seconds = parseInt(diff/1000)%60;
let minutes = parseInt(diff/(60*1000))%60;
let hours = parseInt(diff/(60*60*1000))%24;
label.innerHTML = hours.toString().padStart(2, '0')+':'+minutes.toString().padStart(2, '0')+':'+seconds.toString().padStart(2, '0')+'<br>';
}
},1000);
}
});
}
countDown('.countdown');
<input type="hidden" name="a" id="a" class='duration' value="5000"><label for="a" class="countdown"></label>
<input type="hidden" name="b" id="b" class='duration' value="15000"><label for="b" class="countdown"></label>
<input type="hidden" name="c" id="c" class='duration' value="190000"><label for="c" class="countdown"></label>
<input type="hidden" name="d" id="d" class='duration' value="2003200"><label for="d" class="countdown"></label>
<input type="hidden" name="e" id="e" class='duration' value="20067100"><label for="e" class="countdown"></label>
<input type="hidden" name="f" id="f" class='duration' value="86023104"><label for="f" class="countdown"></label>
$(document).ready(function(){
var interval = 1000;
setInterval(function(){
$('.duration').each(function () {
var t = Number($(this).val()) - interval;
if (t>=0) {
var d = moment.duration(t, 'milliseconds');
$(this).next('.countdown').text([
String(d.hours()).padStart(2,'0'),
String(d.minutes()).padStart(2,'0'),
String(d.seconds()).padStart(2,'0')
].join(':'));
$(this).val(t);
}
});
}, interval);
})
input + span {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min.js"></script>
<input type="hidden" name="a" class='duration' value="5000"><span class="countdown"></span>
<input type="hidden" name="b" class='duration' value="15000"><span class="countdown"></span>
<input type="hidden" name="c" class='duration' value="20000"><span class="countdown"></span>

How to make calculations from the inputs on change?

<!-- This inputs values coming from the date pickers. -->
<input type="text" name="checkin" value="2019-09-11"/>
<input type="text" name="checkout" value="2019-09-13"/>
<input type="text" name="nightprice"/> <!-- When an user write a price -->
<input type="text" name="totalprice"/> <!-- This will be calculated -->
Calculate will be like this ;
The days between checkin and checkout will be calculated and it will be multiplied by days and price.
For example 2019-09-11 between 2019-09-13 is 2 day and if user write 200 on nightprice it will calculate this like 2x200 = 400 and will be placed at totalprice input
my question is how can i do this with jquery without refresh page.
Here's a simple jQuery way to do it. The poor-mans approach would be to just listen to any input change event and re-rerun your calculation. However, if you've got more inputs on your page / form than mentioned in this question (which you likely do) then I would use more specific selectors than simple listening to all inputs. Maybe look into a class? A form onsubmit function? There's plenty of ways to handle that.
const calculatePrice = (checkin, checkout, pricePerNight) => {
checkin = new Date(checkin);
checkout = new Date(checkout);
const dayDiff = Math.round( (checkout - checkin) / (1000 * 60 * 60 * 24 ) );
return dayDiff * pricePerNight;
};
$(document).ready( e => {
const nightPriceInput = $('input[name="nightprice"]');
const checkinInput = $('input[name="checkin"]');
const checkoutInput = $('input[name="checkout"]');
const totalPrice = $('input[name="totalprice"]');
$('input').on('change', () => {
const price = calculatePrice(checkinInput.val(), checkoutInput.val(), nightPriceInput.val());
totalPrice.val(price);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- This inputs values coming from the date pickers. -->
<input type="text" name="checkin" value="2019-09-11"/>
<input type="text" name="checkout" value="2019-09-13"/>
<input type="text" name="nightprice"/> <!-- When an user write a price -->
<input type="text" name="totalprice"/> <!-- This will be calculated -->
var startArray = $("#start").val().split("-");
var finishArray = $("#finish").val().split("-");
var yearDiff = finishArray[0] - startArray[0];
var monthDiff = finishArray[1] - startArray[1];
var dayDiff = finishArray[2] - startArray[2];
$("#price").on('change', function(){
var price = $("#price").val();
var total = ((yearDiff*365) + (monthDiff*30) + (dayDiff)) * price;
$("#total").html("$" + total);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="start" type="text" name="checkin" value="2019-09-11"/>
<input id="finish" type="text" name="checkout" value="2019-09-13"/>
<input id="price" type="text" name="nightprice" value="300"/>
<div id="total">
</div>
See
<input type="text" name="checkin" value="2019-09-11" id="checkin" />
<input type="text" name="checkout" value="2019-09-13" id="checkout" />
<input type="text" name="nightprice" onkeyup="calculate(this)"/> <!-- When an user write a price -->
<input type="text" name="totalprice" id="totalprice" />
<script>
var calculate = function(element) {
// get value
var price = element.value;
var checkin = document.getElementById("checkin");
checkin = checkin.getAttribute('value').replace(/[\-]+/g,'');
var checkout = document.getElementById("checkout");
checkout = checkout.getAttribute('value').replace(/[\-]+/g,'');
var totalprice = document.getElementById('totalprice');
// difference
var difference = checkout - checkin;
// calcule final price
var finalprice = price * difference;
// set final price
totalprice.setAttribute('value', finalprice);
}
</script>

Time multiplication in HH:MM:SS format

I have three fields like "Duration,Repeat,Complete Duration". User will enter the duration in time format(HH:MM:SS) and they will enter the repeat field value like "5,10,4,9,7 etc". Based on the two fields value the complete duration field should be filled.
I have tried using angular NgModel of both text fields and I multiplied the value with repeat field value. But the conversion was not happened properly.
<div>
<input type="value" [(ngModel)]="user.hrDuration">
<input type="value" [(ngModel)]="user.minDuration">
<input type="value" [(ngModel)]="user.secDuration">
</div>
<div>
<input type="value" [(ngModel)]="user.repeat">
</div>
<div>
<input type="value" [(ngModel)]="user.hrDuration*user.repeat">
<input type="value" [(ngModel)]="user.minDuration*user.repeat">
<input type="value" [(ngModel)]="user.secDuration*user.repeat">
</div>
I have tried like this, but the thing is it is directly multiplied the values, I need to convert and then it should multiply with the repeat field value.
Thanks in Advance!
You should subscribe to the input's input event so you'll know when they're changing:
<div>
<input type="value" [(ngModel)]="user.hrDuration" (input)="updateResult()">
<input type="value" [(ngModel)]="user.minDuration" (input)="updateResult()">
<input type="value" [(ngModel)]="user.secDuration" (input)="updateResult()">
</div>
<div>
<input type="value" [(ngModel)]="user.repeat" (input)="updateResult()">
</div>
<div>
<input type="text" [ngModel]="result.hrDuration">
<input type="text" [ngModel]="result.minDuration">
<input type="text" [ngModel]="result.secDuration">
</div>
and then in the Component have the listening method:
export class AppComponent {
user = {
hrDuration: 1,
minDuration: 1,
secDuration: 1,
repeat: 1
}
result = {
hrDuration: this.user.hrDuration * this.user.repeat,
minDuration: this.user.minDuration * this.user.repeat,
secDuration: this.user.secDuration * this.user.repeat
}
updateResult() {
// do your conversion here
this.result.hrDuration = this.user.hrDuration * this.user.repeat;
this.result.minDuration = this.user.minDuration * this.user.repeat;
this.result.secDuration = this.user.secDuration * this.user.repeat;
}
}
Here is a working stackblitz: https://stackblitz.com/edit/angular-2aukww
I think you should use an onchange event listener and a function that returns the result:
HTML:
<div>
<input type="value" [ngModel]="user.hours" (ngModelChange)="getResult()">
<input type="value" [ngModel]="user.minutes" (ngModelChange)="getResult()">
<input type="value" [ngModel]="user.seconds" (ngModelChange)="getResult()">
</div>
<div>
<input type="value" [ngModel]="user.repeat" (ngModelChange)="getResult()">
</div>
<div>
<input type="value" (ngModel)="user.result" readonly>
</div>
JS:
function getResult() {
if (isNaN($scope.user.hours) ||
isNaN($scope.user.minutes) ||
isNaN($scope.user.seconds) ||
isNaN($scope.user.repeat)) return $scope.user.result = "";
var total = ($scope.user.hours*60*60 + $scope.user.minutes*60 + $scope.user.seconds) * $scope.user.repeat;
var hh = Math.floor(total / (60*60));
if ( hh < 10 ) hh = '0' + hh;
var diff = total % (60*60);
var mm = Math.floor(diff / 60);
if ( mm < 10 ) mm = '0' + mm;
var ss = Math.floor(diff % 60);
if ( ss < 10 ) ss = '0' + ss;
$scope.user.result = hh + ':' + mm+ ':' + ss;
// of course you could also output something like
// 'X hours, Y minutes, Z seconds'
}
Showing the result as a single value will show more clearly the final value, since multiplying each variable (hours, minutes and seconds) by the repeats would be less intuitive.

Loan Calculator (jQuery) not working right

I have a loan calculator that I have built using JQuery, HTML, and CSS. It functions ok. The weird thing is I have to refresh the page in order to get it to calculate correctly. I'm not sure what I'm doing (or not doing) correctly. Would love some feedback.
$(document).ready(function() {
// variables
var amount = $('#loanAmount').val();
var yearlyInterestRate = .12;
var monthlyInterestRate = yearlyInterestRate / 12;
var twelveMon = 12;
var eighteenMon = 18;
var twentyFourMon = 24;
var duration = $('input[name=duration]:checked').val();
var calcButton = $('.calculate');
var resetButton = $('.reset');
var monthPay;
$('.results').addClass('hidden');
// Calculate Monthly Payment
calcButton.click(function(event) {
event.preventDefault();
monthPay = (monthlyInterestRate * amount) / [1 - Math.pow((1 + monthlyInterestRate), -duration)];
$('.durationValue').text(duration);
$('.monthlyPayment').text(Math.round(monthPay));
$('.results').removeClass('hidden');
});
resetButton.click(function() {
$(form).reset();
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<section id="loan-calc">
<form id="calculator">
<input type="text" name="loanAmount" id="loanAmount" placeholder="Loan Amount"><br>
<label>Choose your payment duration:</label><br>
<input type="radio" name="duration" value="12" class="duration"> 12 Months<br>
<input type="radio" name="duration" value="18" class="duration"> 18 Months<br>
<input type="radio" name="duration" value="24" class="duration"> 24 Months <br>
<button class="calculate">Calculate</button>
<!-- <button class="rest">Reset</button>-->
</form>
<p class="results">You chose a duration of <span class="durationValue"></span> months and your monthly payment is $<span class="monthlyPayment"></span> at a 12% yearly interest rate.</p>
</section>
You're setting values on document.ready() - so it's even before any of examples in radio will be clicked. Move getting you values into the .click() function
And it's even more efficient to switch from deprecated .click() method to .on('click', function(){}) just in case you'll expand your form in the future
You need to put the vars inside the function that uses them
PS: In a form an input type="reset" /> will reset the form without needing script
$(document).ready(function() {
$('.results').addClass('hidden');
var yearlyInterestRate = .12;
var monthlyInterestRate = yearlyInterestRate / 12;
var twelveMon = 12;
var eighteenMon = 18;
var twentyFourMon = 24;
// Calculate Monthly Payment
$('.calculate').on("click", function(event) {
event.preventDefault();
var amount = $('#loanAmount').val();
var duration = $('input[name=duration]:checked').val();
var monthPay = (monthlyInterestRate * amount) / [1 - Math.pow((1 + monthlyInterestRate), -duration)];
$('.durationValue').text(duration);
$('.monthlyPayment').text(Math.round(monthPay));
$('.results').removeClass('hidden');
});
$('.reset').on("click", function() {
$(form).reset();
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<section id="loan-calc">
<form id="calculator">
<input type="text" name="loanAmount" id="loanAmount" placeholder="Loan Amount"><br>
<label>Choose your payment duration:</label><br>
<input type="radio" name="duration" value="12" class="duration"> 12 Months<br>
<input type="radio" name="duration" value="18" class="duration"> 18 Months<br>
<input type="radio" name="duration" value="24" class="duration"> 24 Months <br>
<button class="calculate">Calculate</button>
<!-- <button class="rest">Reset</button>-->
</form>
<p class="results">You chose a duration of <span class="durationValue"></span> months and your monthly payment is $<span class="monthlyPayment"></span> at a 12% yearly interest rate.</p>
</section>
you take the values of duration and amount on pageload (document ready). if you update the values by filling them in, the variables won't get updated.
move var amount = $('#loanAmount').val(); and var duration = $('input[name=duration]:checked').val(); into the 'onClick' handler so that the amount and duration get updated once you click.

Categories