Simple calculator in JS - javascript

I create a simple web app in pure JS and generally I have few issues which I don't know how to solve. First of all, you can see my demo tool here: http://codepen.io/testerius/pen/EaOPEY
function calculator() {
/*
SPEARMAN
this code below is for Spearman unit
*/
// resource requirements
var spearmanWood = 50;
var spearmanClay = 30;
var spearmanIron = 20;
var spearman = document.getElementById("spearman").value;
// calculate
var spearmanAmount = spearman;
var spearmanWood = spearmanWood * parseInt(spearman);
var spearmanClay = spearmanClay * parseInt(spearman);
var spearmanIron = spearmanIron * parseInt(spearman);
var spearmanProvisions = spearman;
var spearmanTime = spearman * 136; // seconds
// calculate time
var totalSec = spearmanTime;
var hours = Math.floor(totalSec / 3600);
var minutes = Math.floor((totalSec - (hours * 3600)) / 60);
var seconds = totalSec - (hours * 3600) - (minutes * 60);
var spearmanTime = (hours<10 ? "0" + hours : hours) + ":" + (minutes<10 ? "0" + minutes : minutes) + ":" + (seconds<10 ? "0" + seconds : seconds);
// print to table
document.getElementById("spearmanAmount").innerHTML = spearmanAmount;
document.getElementById("spearmanWood").innerHTML = spearmanWood;
document.getElementById("spearmanClay").innerHTML = spearmanClay;
document.getElementById("spearmanIron").innerHTML = spearmanIron;
document.getElementById("spearmanProvisions").innerHTML = spearmanProvisions;
document.getElementById("spearmanTime").innerHTML = spearmanTime;
/*
SWORDSMAN
this code below is for Swordsman unit
*/
// resource requirements
var swordsmanWood = 30;
var swordsmanClay = 30;
var swordsmanIron = 70;
var swordsman = document.getElementById("swordsman").value;
// calculate
var swordsmanAmount = swordsman;
var swordsmanWood = swordsmanWood * parseInt(swordsman);
var swordsmanClay = swordsmanClay * parseInt(swordsman);
var swordsmanIron = swordsmanIron * parseInt(swordsman);
var swordsmanProvisions = swordsman;
var swordsmanTime = swordsman * 194; // seconds
// calculate time
var totalSec = swordsmanTime;
var hours = Math.floor(totalSec / 3600);
var minutes = Math.floor((totalSec - (hours * 3600)) / 60);
var seconds = totalSec - (hours * 3600) - (minutes * 60);
var swordsmanTime = (hours<10 ? "0" + hours : hours) + ":" + (minutes<10 ? "0" + minutes : minutes) + ":" + (seconds<10 ? "0" + seconds : seconds);
// print to table
document.getElementById("swordsmanAmount").innerHTML = swordsmanAmount;
document.getElementById("swordsmanWood").innerHTML = swordsmanWood;
document.getElementById("swordsmanClay").innerHTML = swordsmanClay;
document.getElementById("swordsmanIron").innerHTML = swordsmanIron;
document.getElementById("swordsmanProvisions").innerHTML = swordsmanProvisions;
document.getElementById("swordsmanTime").innerHTML = swordsmanTime;
/*
SUM OF ALL UNITS
this code below is for calculate all units
*/
// all
var allAmount = parseInt(spearmanAmount) + parseInt(swordsmanAmount);
var allWood = parseInt(spearmanWood) + parseInt(swordsmanWood);
var allClay = parseInt(spearmanClay) + parseInt(swordsmanClay);
var allIron = parseInt(spearmanIron) + parseInt(swordsmanIron);
var allProvisions = parseInt(spearmanProvisions) + parseInt(swordsmanProvisions);
var allTime = spearmanTime + swordsmanTime;
// all print
document.getElementById("allAmount").innerHTML = allAmount;
document.getElementById("allWood").innerHTML = allWood;
document.getElementById("allClay").innerHTML = allClay;
document.getElementById("allIron").innerHTML = allIron;
document.getElementById("allProvisions").innerHTML = allProvisions;
document.getElementById("allTime").innerHTML = allTime;
}
How it should work: user type how many units he would create, then JS code makes for him all calculation requirements.
As you can see it works but there are few bugs which I'd like to fix but my lack of knowledge doesn't help me. :P
Problem #1 - how can I hide the requirements table and show it only when user click button Calculate? CSS?
Problem #2 - button Reset clears inputs but doesn't clear results from requirements table, how can I make it work?
Problem #3 - times aren't added as I want, well it's probably string bug but I don't have any idea how to solve it.
Problem #4 - as you can see I repeat some of code, for spearman and swordsman code is very similar. Do you have any idea how I can make it less repeat?
Ok, so that's all what I wanted to ask you guys. Hope someone could help me. Don't get wrong but I quite beginner programmer so my code can be... you know not good. :P

For problem 1, I believe this is a solution. I'm new to Javascript so pretty limited in how I can help.
Here are the lines of code I changed:
In HTML:
<div class="row" id="requirements">
In CSS:
#requirements {
display:none;
}
In JS:
document.getElementById("requirements").style.display="block";

Related

Formatting MomentJS duration above 24 hours

I would like to format a summed up total working hours e.g. 49.75 to this: 49:45.
When I use duration like this:
const dur = moment.duration(49.75, 'hours').asMilliseconds();
moment.utc(dur).format("HH:mm:ss") // 01:45:00
I'll receive 01:45:00 instead of 49:45:00
Is there a way to format (instead of HH) duration without dropping the days?
I think you cannot use format but build it manually:
var dur = moment.duration(49.75, 'hours');
var hours = Math.floor(dur.asHours());
var mins = Math.floor(dur.asMinutes()) - hours * 60;
var sec = Math.floor(dur.asSeconds()) - hours * 60 * 60 - mins * 60;
var result = hours + ":" + mins + ":" + ((sec > 9) ? sec : ("0"+sec));
console.log(result); // 49:45:00
Fiddle
Hope someone will find more elegant way
I recommend you this answer.
You can add a format for the duration, and it works for greater than 24 Hour.
function(input) {
input = input || '';
var out = '';
var dur = moment.duration(input, 'minutes');
return dur.format('HH:mm:ss');
};
I hope it can help you!
EDIT:
This code uses duration-format plugin!
If you are modifying one second at a time, it can be simplified quite a lot (parsing and updating).
Inspiration lifted from this answer: https://stackoverflow.com/a/45629433/11121690
incrementTime: (sectionKey, itemKey) => {
const pad = (number) => `${number > 9 ? number : "0" + number}`;
const timeString = STATS_DATA_UTIL.getByParts(sectionKey, itemKey);
const parts = timeString.split(':');
let uiSecs = parseInt(parts[2]);
let uiMins = parseInt(parts[1]);
let uiHrs = parseInt(parts[0]);
uiSecs++;
if (uiSecs === 60) {
uiSecs = 0; uiMins++;
if (uiMins === 60) uiMins = 0; uiHrs++;
}
const result = `${pad(uiHrs)}:${pad(uiMins)}:${pad(uiSecs)}`;
STATS_DATA_UTIL.setByParts(sectionKey, itemKey, result);
},

nan:nan in Background of Field in PDF form

I have a field which calculates the total hours and minutes for a freelance during the day based on how much they have worked. My issue with this is that before any times are inserted there is the following text always visible in the field (nan:nan) I have below my code I am using, can someone please let me know how to make this not visible, thanks.
function Min2HHMM(nMinutes) {
// convert minutes to HH:MM string and returns formatted time string
return util.printf("%,001.0f:%,202.0f", Math.floor(nMinutes / 60), nMinutes % 60);
}
var T1 = this.getField("Start_Mon_01").value;
var T2 = this.getField("Finish_Mon_01").value;
var T3 = this.getField("Start_Mon_02").value;
var T4 = this.getField("Finish_Mon_02").value;
var start = T1.split(":");
var startmins1 = parseInt(start[0] * 60,10) + parseInt(start[1],10);
var finish = T2.split(":");
var finishmins1 = parseInt(finish[0] * 60,10) + parseInt(finish[1],10);
var start = T3.split(":");
var startmins2 = parseInt(start[0] * 60,10) + parseInt(start[1],10);
var finish = T4.split(":");
var finishmins2 = parseInt(finish[0] * 60,10) + parseInt(finish[1],10);
var timeDiff = finishmins1 - startmins1 + finishmins2 - startmins2;
event.value = Min2HHMM(timeDiff);
Several ways:
function getNum(str) {
return isNaN(str) || str=="" ? 0:parseInt(str,10);
}
var T1 = getNum(this.getField("Start_Mon_01").value);
var T2 = getNum(this.getField("Finish_Mon_01").value);
var T3 = getNum(this.getField("Start_Mon_02").value);
var T4 = getNum(this.getField("Finish_Mon_02").value);
OR
return isNaN(nMinutes) ? "0:00": util.printf("%,001.0f:%,202.0f", Math.floor(nMinutes / 60), nMinutes % 60);
Or
event.value = isNaN(timeDiff)?"0:00": Min2HHMM(timeDiff);
should work.
Also no need to parsint something you multiply.
parseInt(start[0] * 60,10) is the same as start[0] * 60

How do I use setInterval with my form to create an alarm clock?

I'm currently trying to learn JavaScript and I've decided to make things more interesting by actually creating something instead of endless reading & no practice. I'm currently trying to build an alarm clock.
Here's my code:
http://codepen.io/anon/pen/dCsax
function wakeup() {
window.location = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
}
I need to create another function that uses setInterval to check every few seconds if the time set in that form is equal to the current time, and if it is, execute the wakeup function that plays Rick Astley - Never Gonna Give You Up.
I don't know how to write this piece of code. Could someone please help me out so I can see how it's done?
Thanks in advance.
For a pure JS solution (no libraries) you should read about Date object
I've forked your example on codepen like this:
function set_alarm() {
var h = document.getElementById('h').value;
var m = document.getElementById('m').value;
var t = document.getElementById('t').value;
if ( t == 'PM' ) h+= 12;
var now = new Date();
var d = new Date();
d.setHours(h);
d.setMinutes(m);
d.setSeconds(0);
var delta = d.getTime() - now.getTime();
if (delta < 0) delta = -delta;
setTimeout(wakeup,delta);
}
This should give you a hint about what to do.
You can also try using one of the many libraries about dates, expecially moment.js
I added an id to your button, and on click set up the timer function as below:
<input id="scheduleTimer" type="button" value="Schedule alarm"></input>
function getTimeoutSec() {
var dt = new Date();
var currSecs = dt.getSeconds() + (60 * dt.getMinutes()) + (60 * 60 * dt.getHours());
var am_pm = document.getElementById('t').value;
var formHour = parseInt(document.getElementById('h').value);
if(am_pm == 'PM') {
formHour += 12;
}
var formMin = parseInt(document.getElementById('m').value);
var formSeconds = (formHour * 3600) + (formMin * 60);
return formSeconds - currSecs;
}
window.onload = function() {
var scheduleTimerButton = document.getElementById('scheduleTimer');
scheduleTimerButton.addEventListener('click', function() {
var secRemaining = getTimeoutSec();
setTimeout(wakeup, secRemaining * 1000);
}, false);
};
Link to CodePen
Here is an example function
function scheduleAlarm() {
var h = document.getElementById('h').value;
var m = document.getElementById('m').value;
var t = document.getElementById('t').value;
alert("Successfully scheduled alram!");
setInterval(function(){
var date = new Date;
var hours = date.getHours();
var minutes = date.getMinutes();
var ampm = hours >= 12 ? 'pm' : 'am';
hours = hours % 12;
hours = hours ? hours : 12; // the hour '0' should be '12'
if (h == hours && m == minutes && t == ampm){
alert("Time to go to school, wake up!")
}
}, 5000); // will run every 5 seconds
}
Demo: CodePen

Having Trouble Creating A Timer To Count From a Given Time

I need for a clock to count from a specific time. e.g. Time is 20:08:00 and then to count from there. I have searched high and low for an answer and no one has specifically come up with an answer(that Ive seen). So my normal clock is like this.
<script type="text/javascript">
function clock()
{
var digital = new Date();
var hours = digital.getHours();
var minutes = digital.getMinutes();
var seconds = digital.getSeconds();
if (minutes <= 9) minutes = "0" + minutes;
if (seconds <= 9) seconds = "0" + seconds;
dispTime = hours + ":" + minutes + ":" + seconds;
var basicclock = document.getElementById('basicclock');
basicclock.innerHTML = dispTime;
setTimeout("clock()", 1000);
}
clock();
</script>
So all I need is the time to start at say 20:08:00 (or a variable of time). I am wondering if it better to use a timer to achieve a set time and to count from that???
Any help would be appreciated.
First: Please try to extensively search SO for answers before asking questions, many helpful responses can be found if you look. ;)
If you are trying to countdown to a certain time/date I would recommend the answer found HERE
All code credit goes to author's answer above.
HTML - for display
<span id="days"></span>
<span id="hours"></span>
<span id="minutes"></span>
<span id="seconds"></span>
Script (keep formatting and just modify the 4th line down for your target date)
setInterval(function(){
// set whatever future date / time you want here, together with
// your timezone setting...
var future = new Date("Sep 20 2014 21:15:00 GMT+0200");
var now = new Date();
var difference = Math.floor((future - now) / 1000);
var seconds = fixIntegers(difference % 60);
difference = Math.floor(difference / 60);
var minutes = fixIntegers(difference % 60);
difference = Math.floor(difference / 60);
var hours = fixIntegers(difference % 24);
difference = Math.floor(difference / 24);
var days = difference;
$("#seconds").text(seconds + "s");
$("#minutes").text(minutes + "m");
$("#hours").text(hours + "h");
$("#days").text(days + "d");
}, 1000);
function fixIntegers(integer)
{
if (integer < 0)
integer = 0;
if (integer < 10)
return "0" + integer;
return "" + integer;
}
DEMO OF THE ABOVE CODE
I would also look at these are other interesting solutions found on this post here HERE

Creating timecode from frames

I have a FPS (frames per second) of 30. I have a total FPS so far, lets say 1020. I want to display this as a formatted timecode, as below.
var fps = 30;
var currentFrame = 1020;
var resultString = ; // HH:MM:SS:FF
Are there any Javascript functions built in for formatting like this?
To be clear, I need the string to be formatted as such: HH:MM:SS:FF
Are you looking for a built-in JS function?..
var FF = currentFrame % fps;
var seconds = (currentFrame - FF) / fps;
var SS = seconds % 60;
var minutes = (seconds - SS) / 60;
var MM = minutes % 60;
var HH = (minutes - MM) / 60;
There you go.
It can be done in much simpler way:
function displayTime(currentFrame) {
var fps = 30;
var h = Math.floor(currentFrame/(60*60*fps));
var m = (Math.floor(currentFrame/(60*fps))) % 60;
var s = (Math.floor(currentFrame/fps)) % 60;
var f = currentFrame % fps;
return showTwoDigits(h) + ":" + showTwoDigits(m) + ":" + showTwoDigits(s) + ":" + showTwoDigits(f);
}
function showTwoDigits(number) {
return ("00" + number).slice(-2);
}
console.log("Frame 1020 will be displayed as " + displayTime(1020));
Frame 1020 will be displayed as 00:00:34:00
showTwoDigits
This help function takes a number (example: 6), adds "00" before it, which makes it a string (example: "006"). Then it slices back 2 positions from the end (will give "06").
displayTime
var h
It calculates hours by dividing the frames by 60*60*30 frames per hours. An hour has 60*60*30 frames.
var m
Minutes are calculated in the same way by dividing it by 60*30 frames per minute. But note here that this could result in a number like 80 minutes, because it is the TOTAL amount of minutes. The script has to take in account only the remainder after dividing this amount by 60. Here the modulus comes into play. 80 % 60 will give 20, the number we are looking for.
var s
In a similar way the seconds are calculated by dividing the frames by 30 frames per second and then take it modulus 60 (so that 65 seconds will be represented as 5).
Try this:
var fps = 30;
var currentFrame = 169;
var SS = Math.floor(currentFrame / fps);
var MM = Math.floor(SS / 60);
var HH = Math.floor(MM / 60);
var FF = currentFrame - (SS * fps);
function pad(str, width, what, left) {
str = String(str);
what = String(what);
var w = width - str.length;
if (left) {
return (new Array(w + 1)).join(what) + str;
} else {
return str + (new Array(w + 1)).join(what);
}
}
var i,
timecode = [HH, MM, SS, FF];
for (i = 0; i < timecode.length; i += 1) {
timecode[i] = pad(timecode[i], 2, 0, true);
}
var resultString = timecode.join(':'); // HH:MM:SS:FF
you can also use the date object see here. Just make something like:
var d = new Date( yourframetime + new Date().getTime() );
var str = d.getHours()+':'+ d.getMinutes()+ ':' + d.getSeconds() + .......
than you can use all the string functions of the object, or make your own with it.
Old post, but I was using this recently and a combination of Alexander's and Lucas's code give the correct results. The checked version actually breaks on really large frame counts ( I think due to Math.floor).
Code is:
var fps = 30;
var currentFrame = 169;
var FF = currentFrame % fps;
var seconds = (currentFrame - FF) / fps;
var SS = seconds % 60;
var minutes = (seconds - SS) / 60;
var MM = minutes % 60;
var HH = (minutes - MM) / 60;
function pad(str, width, what, left) {
str = String(str);
what = String(what);
var w = width - str.length;
if (left) {
return (new Array(w + 1)).join(what) + str;
} else {
return str + (new Array(w + 1)).join(what);
}
}
var i,
timecode = [HH, MM, SS, FF];
for (i = 0; i < timecode.length; i += 1) {
timecode[i] = pad(timecode[i], 2, 0, true);
}
var resultString = timecode.join(':'); // HH:MM:SS:FF
For Anyone interested with the swift version of the showTwoDigits function, here is a working code sample:
func showTwoDigits(number:Float) -> (String){
var string = ("00" + String(format:"%.f", number))
var range = Range(start: (advance(string.endIndex, -2)), end: string.endIndex)
var cutStr = string.substringWithRange(range)
return cutStr
}
This function converts to HH:MM:SS:FF correctly :
var convertTime = function (frames, fps) {
fps = (typeof fps !== 'undefined' ? fps : 30 );
var pad = function(input) {return (input < 10) ? "0" + input : input;},
seconds = (typeof frames !== 'undefined' ? frames / fps : 0 );
return [
pad(Math.floor(seconds / 3600)),
pad(Math.floor(seconds % 3600 / 60)),
pad(Math.floor(seconds % 60)),
pad(Math.floor(frames % fps))
].join(':');
}
Demo
var convertTime = function (frames, fps) {
fps = (typeof fps !== 'undefined' ? fps : 30 );
var pad = function(input) {return (input < 10) ? "0" + input : input;},
seconds = (typeof frames !== 'undefined' ? frames / fps : 0 );
return [
pad(Math.floor(seconds / 3600)),
pad(Math.floor(seconds % 3600 / 60)),
pad(Math.floor(seconds % 60)),
pad(Math.floor(frames % fps))
].join(':');
}
document.body.innerHTML = '<pre>' + JSON.stringify({
5 : convertTime(5),
50 : convertTime(50),
126 : convertTime(126),
1156 : convertTime(1156),
9178 : convertTime(9178),
13555 : convertTime(13555)
}, null, '\t') + '</pre>';
See also this Fiddle.

Categories