0

I have an html here which executes a simple alarm based on the input time. I'm running nodejs webserver and this is my index.html

My problem is after clicking the "set alarm" button the function initiates but of course after reloading the page everything is gone. I've read about local storage but I don't know how to implement it in this scenario. I tried using garlic.js but only works on input forms like text field and checkboxes, not a button that executes a function.

var alarmSound = new Audio();
alarmSound.src = 'alarm.mp3';
var alarmTimer;

function setAlarm(button) {
  var ms = document.getElementById('alarmTime').valueAsNumber;
  if (isNaN(ms)) {
    alert('Invalid Date');
    return;
  }

  var alarm = new Date(ms);
  var alarmTime = new Date(alarm.getUTCFullYear(), alarm.getUTCMonth(), alarm.getUTCDate(), alarm.getUTCHours(), alarm.getUTCMinutes(), alarm.getUTCSeconds());

  var differenceInMs = alarmTime.getTime() - (new Date()).getTime();

  if (differenceInMs < 0) {
    alert('Specified time is already passed');
    return;
  }

  alarmTimer = setTimeout(initAlarm, differenceInMs);
  button.innerText = 'Cancel Alarm';
  button.setAttribute('onclick', 'cancelAlarm(this);');
};

function cancelAlarm(button) {
  clearTimeout(alarmTimer);
  button.innerText = 'Set Alarm';
  button.setAttribute('onclick', 'setAlarm(this);')
};

function initAlarm() {
  alarmSound.play();
  document.getElementById('alarmOptions').style.display = '';
};

function stopAlarm() {
  alarmSound.pause();
  alarmSound.currentTime = 0;
  document.getElementById('alarmOptions').style.display = 'none';
  cancelAlarm(document.getElementById('alarmButton'));
};

function snooze() {
  stopAlarm();
  alarmTimer = setTimeout(initAlarm, 6000); // 5 * 60 * 100
};
<input id="alarmTime" type="datetime-local">
<button onclick="alarmButton" id="setAlarm(this);">Set Alarm</button>

<div id="alarmOptions" style="display: none;">
  <button onclick="snooze();">Snooze 5 minutes</button>
  <button onclick="stopAlarm();">Stop Alarm</button>
</div>
mplungjan
  • 134,906
  • 25
  • 152
  • 209
Onjieee
  • 39
  • 7
  • Please fix the console error. You want to use localStorage/sessionStorage – mplungjan Aug 22 '18 at 17:48
  • Like you allready mentioned i would make use of the localstorage. You can simply set and get string values into the storage and query them when your page is loading. – Martin Godzina Aug 22 '18 at 17:51

2 Answers2

2

Local storage would be a good way to keep track of the alarm time between sessions/page refreshes.

To save alarmTime to local storage, use:

window.localStorage.setItem('alarmTime', alarmTime)

Then when you want to use alarmTime, retrieve it from local storage with:

window.localStorage.getItem('alarmTime')

One thing to note is that local storage only stores strings, at least in the more popular browsers (see this post), so keep that in mind here.

See MDN docs on local storage for more: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

To have your function execute again after the page is refreshed, you can add a line like this:

document.onload = () => setAlarm(button);

Which will cause setAlarm to be called when the page finishes loading.

Edit

Here is a rough layout of how you can incorporate the above information into your code. I think it's actually better to store ms in local storage rather than alarmTime so that you can populate the input with ms from local storage when your document loads.

document.onload = function() {
    var ms = window.localStorage.getItem('ms');
    if (ms) {
        populateTimeInput(ms);
        var alarmButton = document.querySelector('#alarmButton');
        setAlarm(alarmButton);
    }
}

function populateTimeInput(newTime) {
    var timeInput = document.querySelector('#alarmTime');
    timeInput.value = newTime;
}

function setAlarm(button) {
    var ms = document.getElementById('alarmTime').valueAsNumber;
    if (isNaN(ms)) {
        alert('Invalid Date');
        return;
    }

    window.localStorage.setItem('ms', ms);

    // then everything else is the same
}

function cancelAlarm(button) {
    window.localStorage.clear();
    // and everything else the same
}

Three main things this code adds:

  • When your page finishes loading, this code will check local storage for ms, if it finds a value for ms, it populates the alarmTime input with the value it's found and then calls setAlarm automatically.
  • When setAlarm is called, save ms to local storage (if ms has a valid value).
  • When cancelAlarm is called, clear local storage.

This is perhaps not the most elegant way to handle all of this, but I hope it at least gets you going in the right direction — keep iterating!

Henry Woody
  • 9,777
  • 6
  • 27
  • 37
  • The alarmTime would be stored but will the function still be excecuted after page reload? – Onjieee Aug 22 '18 at 18:12
  • If you want a function to execute after a page reload that'll need to be handled with `document.onload` or `window.onload`. (See: https://stackoverflow.com/questions/807878/javascript-that-executes-after-page-load). Made an edit to the post – Henry Woody Aug 22 '18 at 18:21
  • Where exactly should I put the `document.onload` where in the code can I use the `setItem ` and `getItem ` function. Can I just store the set date and bring it back after page refresh and also execute a function that will click the Set Time button after page refresh? – Onjieee Aug 22 '18 at 19:13
  • @Onjieee made some edits, see the last section for how you might use these ideas – Henry Woody Aug 22 '18 at 19:48
  • Thank you very much! Will try this as soon as I get home :) – Onjieee Aug 23 '18 at 01:28
0

Try this, I am using setInterval instead of setTimer and I am storing the remaining time in local storage and decreasing it by 500 after every 0.5sec.

var alarmSound = new Audio();
alarmSound.src = 'alarm.mp3';
var alarmTimer;

function setAlarm(button) {
  var ms = document.getElementById('alarmTime').valueAsNumber;
  if (isNaN(ms)) {
    alert('Invalid Date');
    return;
  }
  
  var alarm = new Date(ms);
  var alarmTime = new Date(alarm.getUTCFullYear(), alarm.getUTCMonth(), alarm.getUTCDate(), alarm.getUTCHours(), alarm.getUTCMinutes(), alarm.getUTCSeconds());

  var differenceInMs = alarmTime.getTime() - (new Date()).getTime();

  if (differenceInMs < 0) {
    alert('Specified time is already passed');
    return;
  }
  startTimer(differenceInMs)
  button.innerText = 'Cancel Alarm';
  button.setAttribute('onclick', 'cancelAlarm(this);');
};

function startTimer(time){
  localStorage.setItem("timeLeft",time)
  alarmTimer = setInterval(initAlarm, 500);
}

function cancelAlarm(button) {
  clearInterval(alarmTimer);
  button.innerText = 'Set Alarm';
  button.setAttribute('onclick', 'setAlarm(this);')
};

function initAlarm() {
  var timeLeft = parseInt(localStorage.getItem("timeLeft"))-500;
  if(timeLeft <= 0){
  alarmSound.play();
  document.getElementById('alarmOptions').style.display = '';
  } else {
    localStorage.setItem("timeLeft",timeLeft)
  }
};

function stopAlarm() {
  alarmSound.pause();
  alarmSound.currentTime = 0;
  document.getElementById('alarmOptions').style.display = 'none';
  cancelAlarm(document.getElementById('alarmButton'));
};

function snooze() {
  stopAlarm();
  alarmTimer = startTimer(6000); // 5 * 60 * 100
};
<input id="alarmTime" type="datetime-local">
<button onclick="alarmButton" id="setAlarm(this);">Set Alarm</button>

<div id="alarmOptions" style="display: none;">
  <button onclick="snooze();">Snooze 5 minutes</button>
  <button onclick="stopAlarm();">Stop Alarm</button>
</div>