JSFiddle - React, Tailwind, and code Playground

by sungsoonz

HTML

<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="//use.fontawesome.com/05799db3cf.js"></script>
<div class="sb-timer-wrapper">
  <button id="sb-timer-edit" class="btn" onclick="stop()" style="display:none;"><i class="fa fa-pencil"></i></button>
  <button id="sb-timer-start" class="btn btn-primary" onclick="start()"><i class="fa fa-circle-o-notch"></i> Start</button>
  <button id="sb-timer-stop" class="btn btn-danger" onclick="stop()" data-toggle="tooltip" style="display:none;">
    <i class="fa fa-circle-o-notch fa-spin"></i> Stop
  </button>
  <div class="sb-timer">
    <span id="lblhr">00</span>:<span id="lblmin">00</span>:<span id="lblsec">00</span>
  </div>
</div>


<!-- Modal -->
<div id="sb-timer-modal" class="modal fade" role="dialog">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal">&times;</button>
        <h4 class="modal-title">Timesheet Entry</h4>
      </div>
      <div class="modal-body">
        <div class="row">
          <div class="col-sm-4">
            <div class="form-group">
              <label>Started:</label>
              <input id="started" type="text" class="form-control">
            </div>
          </div>
          <div class="col-sm-4">
            <div class="form-group">
              <label>Ended:</label>
              <input id="ended" type="text" class="form-control">
            </div>
          </div>
        </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-primary" data-dismiss="modal" onclick="">Save</button>
        <button type="button" class="btn" data-dismiss="modal" onclick="reset()">Delete</button>
      </div>
    </div>
  </div>
</div>

CSS

span {
  padding: 5px;
  border-radius: 4px;
}

.sb-timer {
  padding: 2px;
  margin: 10px;
  display: inline-block;
}

.sb-timer-wrapper {
  padding: 5px;
}

.btn {
  border-radius: 6px;
  color: #ffffff;
  font-size: 14px;
  border: 0;
  text-decoration: none;
}

.modal-footer {
  text-align: center;
}

JavaScript

var d = new Date(),
  d2 = new Date(d.getTime() - (d.getTimezoneOffset() * 60000)).toISOString();

var Timer = function() {
  this.time = {
    sec: 00,
    min: 00,
    hr: 00
  };
  this.startedTime = d.toLocaleTimeString();
  this.endedTime = null;
  this.max = 59;
  this.interval = null;
  this.print = function(str) {
    var _time = this.time[str].toString().length == 1 ? "0" + this.time[str] : this.time[str];
    document.getElementById("lbl" + str).innerHTML = _time;
  };
  this.printAll = function() {
    this.print("sec");
    this.print("min");
    this.print("hr");
  };
  this.update = function(str) {
    this.time[str]++;
    this.time[str] = this.time[str] % 60;
    if (this.time[str] == 0) {
      str == "sec" ? this.update("min") : this.update("hr");
    }
    this.print(str);
  };
  this.validateTimer = function() {
    var className = "";
    var secs = this.time.sec + (this.time.min * 60) + (this.time.hr * 60 * 60);
    var element = document.getElementsByTagName("span");
    document.getElementById("lblsec").className = className;
  };
  this.init = function(_hr, _min, _sec) {
    this.time["hr"] = _hr ? _hr : 0;
    this.time["min"] = _min ? _min : 0;
    this.time["sec"] = _sec ? _sec : 0;
    this.printAll();
  };
  this.startTimer = function() {
    this.time.hr = $('#lblhr').text();
    this.time.min = $('#lblmin').text();
    this.time.sec = $('#lblsec').text();
    if (this.time['hr'] === '00' && this.time['min'] === '00' && this.time['sec'] === '00') {
      this.init(0, 0, 0);
      this.startedTime = d.toLocaleTimeString();
    } else {
      this.init(this.time["hr"], this.time["min"], this.time["sec"]);
    }
    if (this.interval) this.stopTimer();
    this.interval = setInterval(function() {
      timer.update("sec");
      timer.validateTimer();
    }, 1000);
  };
  this.stopTimer = function() {
    window.clearInterval(this.interval);
  };
  
  this.open_modal = function() {
  	this.endedTime =...