const Timer = function (config) {
this.id = config.id;
this.prefixedId = `${config.type}-${config.id}`;
this.$device = document.getElementById(`${this.prefixedId}`);
this.$display = document.getElementById(`${this.prefixedId}-display`);
this.$device.onclick = this.hub.bind(this);
};
Timer.prototype = {
intervalId: null,
hub: function (event) {
let role = event.target.id.split('-')[2];
switch (role) {
case 'start':
this.initialTime = this.getInputs(this.prefixedId);
this.intervalId = this.start(this.initialTime, this.prefixedId);
break;
case 'pause':
this.pause(this.prefixedId);
break;
case 'remove':
this.pause(this.prefixedId);
this.remove(this.prefixedId);
break;
}
},
getInputs: function (prefixedId) {
return (
Number(document.getElementById(`${prefixedId}-hours-input`).value) * 3600 +
Number(document.getElementById(`${prefixedId}-minutes-input`).value) * 60 +
Number(document.getElementById(`${prefixedId}-seconds-input`).value)
);
},
start: function (initialTime, prefixedId) {
let $display = document.getElementById(prefixedId + '-display');
if ($display.style.display === 'none') { $display.style.display = 'block'; }
$display.textContent = TimerHandler.cycle(initialTime);
$display = null;
return setInterval(function () {
this.initialTime--;
(this.initialTime === 0 && this.pause());
document.getElementById(prefixedId + '-display').textContent = TimerHandler.cycle(this.initialTime);
}.bind(this), 1000);
},
pause: function () {
if (this.intervalId) { clearInterval(this.intervalId); }
this.intervalId = null;
},
remove: function () {
this.$display = null;
this.$device.onclick = null;
this.$device.remove();
}
};
const $addTimerBtn = document.getElementById('add-timer-btn');
const $deviceNameInput = document.getElementById('device-name-input');
const $devices = document.getElementById('devices');
const timerTemplate = document.getElementById('timer-template').innerHTML;
function createTemplate (template, config) {
for (let key of Object.keys(config)) {
let regex = new RegExp('{{' + key + '}}', 'g');
template = template.replace(regex, config[key]);
}
return template.trim();
}
function createTimer (config) {
let htmlString = createTemplate(timerTemplate, config);
$devices.insertAdjacentHTML('beforeend', htmlString);
return new Timer(config);
}
$addTimerBtn.addEventListener('click', (function (id) {
return function (e) {
const config = {
id: id++,
name: $deviceNameInput.value,
type: e.target.dataset.type
};
createTimer(config);
}
})(0));
const TimerHandler = (function () {
const _toClockFormat = function (seconds) {
function checkZero(x) {
if (x.length < 2) {
return '0' + x;
}
return x;
};
return (
checkZero(String(seconds / 3600 | 0)) + ' : ' +
checkZero(String(Math.floor((seconds % 3600) / 60))) + ' : ' +
checkZero(String(seconds % 60))
);
},
_cycle = function (instructions) {
return function (secondsLeft) {
return instructions.reduce(function (format, instruction) {
return instruction(format);
}, secondsLeft);
}
};
return {
cycle: _cycle([_toClockFormat])
}
}());
[id*="config-input"] > label {
display: block;
};
<!DOCTYPE html>
<head>
<link rel="stylesheet" href="timer.css" />
</head>
<body>
<nav>
<label for="device-name-input">Name</label>
<input type="text" id="device-name-input">
<button id="add-timer-btn" data-type="timer">Add timer</button>
</nav>
<main id="devices"></main>
<script id="timer-template" type="text/template">
<div id="{{type}}-{{id}}">
<p>{{name}}</p>
<p>{{type}}</p>
<div id="{{type}}-{{id}}-config-input" style="display: block">
<label for="hours">Hours</label>
<input id="{{type}}-{{id}}-hours-input" type="text" id="hours" value="00">
<label for="minutes">Minutes</label>
<input id="{{type}}-{{id}}-minutes-input" type="text" id="minutes" value="00">
<label for="seconds">Seconds</label>
<input id="{{type}}-{{id}}-seconds-input" type="text" id="seconds" value="00">
</div>
<div id="{{type}}-{{id}}-display" style="display: none"></div>
<div>
<button id="{{type}}-{{id}}-start-btn">Start</button>
<button id="{{type}}-{{id}}-pause-btn">Pause</button>
<button id="{{type}}-{{id}}-reset-btn">Reset</button>
<button id="{{type}}-{{id}}-remove-btn">X</button>
</div>
</div>
</script>
<script src="App.js"></script>
<script src="Timer.js"></script>
<script src ="TimerHandler.js"></script>
</body>
</html>