Simple Time Picker In Pure Javascript CSS (Free Download)

Welcome to a tutorial on how to create a time picker using pure Javascript and CSS. Yes, there are plenty of time picker plugins available on the Internet. But some of them require a third-party library, and it simply does not make sense to load an entire library for a single-time picker. So here it is, a sharing of my simple time picker – Read on!

ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.

 

TABLE OF CONTENTS

Download & Demo How It Works Useful Bits
The End

 

 

DOWNLOAD & DEMO

Here is the link to download the script, and a short examples section on how to quickly use it in your own projects.

 

QUICK NOTES

If you spot a bug, feel free to comment below. I try to answer short questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

EXAMPLE CODE DOWNLOAD

Click here to download the source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

DEMO & HOW TO USE

BASIC TIME PICKER

1-basic.html
<!-- (A) LOAD THE CSS + JS -->
<link href="time-pick.css" rel="stylesheet">
<script src="time-pick.js"></script>
 
<!-- (B) POPUP TIME PICKER -->
<input type="text" id="demoA"/>
 
<!-- (C) ATTACH -->
<script>
tp.attach({
  target: document.getElementById("demoA")
});
</script>
  1. Include the time picker Javascript and CSS files. Doh.
  2. Define a <input type="text"/> as usual.
  3. Finally, use tp.attach({ target : HTML FIELD }) to attach the time picker.

 

TIME PICKER OPTIONS

2-options.html
tp.attach({
  target: document.getElementById("demoB"),
  "24": true, // 24 HOURS
  after: (time) => { alert(time); } // RUN FUNCTION AFTER SELECT
});

That’s all. This simple time picker only has 2 optional options:

  • 24 Use 24 hour time format, defaults to false.
  • after Function to call after selecting the time.

 

 

HOW IT WORKS

With that, let us now move into more details on how the time picker works – This section is for the people who want “deep customizations” on the time picker.

 

PART 1) TIME PICKER INITIALIZE

time-pick.js
// (A) INIT - GENERATE TIME PICKER HTML
hwrap : null, // entire html time picker
hhr : null, // html hour value
hmin : null, // html min value
hap : null, // html am/pm value
init : () => {
  // (A1) ADD TIME PICKER TO BODY
  tp.hwrap = document.createElement("div");
  tp.hwrap.id = "tp-wrap";
  document.body.appendChild(tp.hwrap);
 
  // (A2) TIME PICKER INNER HTML
  tp.hwrap.innerHTML =
  `<div id="tp-box">
    <div class="tp-cell" id="tp-hr">
      <div class="tp-up">&#65087;</div> <div class="tp-val">0</div> <div class="tp-down">&#65088;</div>
    </div>
    <div class="tp-cell" id="tp-min">
      <div class="tp-up">&#65087;</div> <div class="tp-val">0</div> <div class="tp-down">&#65088;</div>
    </div>
    <div class="tp-cell" id="tp-ap">
      <div class="tp-up">&#65087;</div> <div class="tp-val">AM</div> <div class="tp-down">&#65088;</div>
    </div>
    <button id="tp-close" onclick="tp.hwrap.classList.remove('show')">Close</button>
    <button id="tp-set" onclick="tp.set()">Set</button>
  </div>`;
 
  // (A3) GET VALUE ELEMENTS + SET CLICK ACTIONS
  for (let segment of ["hr", "min", "ap"]) {
    let up = tp.hwrap.querySelector(`#tp-${segment} .tp-up`),
        down = tp.hwrap.querySelector(`#tp-${segment} .tp-down`);
    tp["h"+segment] = tp.hwrap.querySelector(`#tp-${segment} .tp-val`);
 
    if (segment=="ap") {
      up.onclick = () => { tp.spin(true, segment); };
      down.onclick = () => { tp.spin(true, segment); };
    } else {
      up.onmousedown = () => { tp.spin(true, segment); };
      down.onmousedown = () => { tp.spin(false, segment); };
      up.onmouseup = () => { tp.spin(null); };
      down.onmouseup = () => { tp.spin(null); };
      up.onmouseleave = () => { tp.spin(null); };
      down.onmouseleave = () => { tp.spin(null); };
    }
  }
},
document.addEventListener("DOMContentLoaded", tp.init);

The first thing that runs on page load is tp.init(). It may look intimidating, but keep calm and look carefully. All it does is generate the time picker HTML <div id="tp-wrap"> to the page – All the inner HTML is right there are A2.

 

 

PART 2) TIME PICKER HOUR/MIN/AM/PM SPINNER

time-pick.js
// (B) SPIN HOUR/MIN/AM/PM
// direction : true (up), false (down), null (stop)
// segment : "hr", "min", "ap" (am/pm)
timer : null, // for "continous" time spin
minhr : 1, // min spin limit for hour
maxhr : 12, // max spin limit for hour
minmin : 0, // min spin limit for minute
maxmin : 59, // max spin limit for minute
spin : (direction, segment) => {
  // (B1) CLEAR TIMER
  if (direction==null) { if (tp.timer!=null) {
    clearTimeout(tp.timer);
    tp.timer = null;
  }}
 
  // (B2) SPIN FOR AM/PM
  else if (segment=="ap") { tp.hap.innerHTML = tp.hap.innerHTML=="AM" ? "PM" : "AM"; }
 
  // (B3) SPIN FOR HR/MIN
  else {
    // (B3-1) INCREMENT/DECREMENT
    let next = +tp["h"+segment].innerHTML;
    next = direction ? next+1 : next-1;
 
    // (B3-2) MIN/MAX
    if (segment=="hr") {
      if (next > tp.maxhr) { next = tp.maxhr; }
      if (next < tp.minhr) { next = tp.minhr; }
    } else {
      if (next > tp.maxmin) { next = tp.maxmin; }
      if (next < tp.minmin) { next = tp.minmin; }
    }
 
    // (B3-3) SET VALUE
    if (next<10) { next = "0"+next; }
    tp["h"+segment].innerHTML = next;
 
    // (B3-4) KEEP ROLLING - LOWER TIMEOUT WILL SPIN FASTER
    tp.timer = setTimeout(() => { tp.spin(direction, segment); }, 100);
  }
},

Next, I figured that it will be stupid to click on the hour/minute hundreds of times to set it. So this function is the essential driver behind “hold mouse down to spin”.

 

 

PART 3) ATTACH TIME PICKER

time-pick.js
// (C) ATTACH TIME PICKER TO HTML FIELD
// target : html field to attach to
// 24 : 24 hours time? default false.
// after : optional, function to run after selecting time
attach : (instance) => {
  // (C1) READONLY FIELD + NO AUTOCOMPLETE
  // IMPORTANT, PREVENTS ON-SCREEN KEYBOARD
  instance.target.readOnly = true;
  instance.target.setAttribute("autocomplete", "off");
 
  // (C2) DEFAULT 12 HOURS MODE
  if (instance["24"]==undefined) { instance["24"] = false; }
 
  // (C3) CLICK TO OPEN TIME PICKER
  instance.target.addEventListener("click", () => { tp.show(instance); });
},

You already know this one, we call tp.attach() to attach the time picker to an <input> field. Basically, we attach an onclick to display the time picker.

 

 

PART 4) DISPLAY THE TIME PICKER

time-pick.js
// (D) SHOW TIME PICKER
setfield : null, // set selected time to this html field
set24 : false, // 24 hours mode? default false.
setafter : null, // run this after selecting time
show : (instance) => {
  // (D1) INIT FIELDS TO SET + OPTIONS
  tp.setfield = instance.target;
  tp.setafter = instance.after;
  tp.set24 = instance["24"];
  tp.minhr = tp.set24 ? 0 : 1 ;
  tp.maxhr = tp.set24 ? 23 : 12 ;
 
  // (D2) READ CURRENT VALUE
  let val = tp.setfield.value;
  if (val=="") {
    tp.hhr.innerHTML = "0"+tp.minhr;
    tp.hmin.innerHTML = "0"+tp.minmin;
    tp.hap.innerHTML = "AM";
  } else {
    tp.hhr.innerHTML = val.substring(0, 2);
    if (tp.set24) {
      tp.hmin.innerHTML = val.substring(2, 4);
    } else {
      tp.hmin.innerHTML = val.substring(3, 5);
      tp.hap.innerHTML = val.substring(6, 8);
    }
  }
 
  // (D3) SHOW TIME PICKER
  if (tp.set24) { tp.hwrap.classList.add("tp-24"); }
  else { tp.hwrap.classList.remove("tp-24"); }
  tp.hwrap.classList.add("show");
},

tp.show() is called when the user clicks on an attached <input> field. Not going to explain line-by-line, but it sets some internal flags, then adapts the selected time from the field to the time picker.

 

 

PART 5) SET SELECTED TIME

time-pick.js
// (E) SET TIME
set : () => {
  // (E1) TIME TO FIELD
  if (tp.set24) {
    tp.setfield.value = tp.hhr.innerHTML + tp.hmin.innerHTML;
  } else {
    tp.setfield.value = tp.hhr.innerHTML + ":" + tp.hmin.innerHTML + " " + tp.hap.innerHTML;
  }
  tp.hwrap.classList.remove("show");
 
  // (E2) RUN AFTER, IF SET
  if (tp.setafter) { tp.setafter(tp.setfield.value); }
}

Lastly, this should be very obvious – Set the selected time onto the HTML field.

 

USEFUL BITS

That’s all for this project, and here is a small section on some extras that may be useful to you.

 

CHANGING THE TIME FORMAT

  • Modify set(), section E1.
  • Also, remember to change how it adapts existing values in show(), section D2.

 

COMPATIBILITY CHECKS

This time picker will work on all Grade A modern browsers.

 

LINKS & REFERENCES

 

THE END

Thank you for reading, and we have come to the end of this guide. I hope that it has helped you to create a better website, and if you have anything to share with this guide, please feel free to comment below. Good luck and happy coding!

Leave a Comment

Your email address will not be published.