An opinionated clock-style vanilla-js timepicker.
See README on GitHub for details.
<input data-clocklet>
<input data-clocklet value="12:34">
<input data-clocklet="format: h:mm a" value="1:23 pm">
CodePen<div style="display: flex">
<div>
<h3>without input element</h3>
<div id="clocklet-inline-container"></div>
<script>
const element = document.getElementById("clocklet-inline-container");
clocklet.inline(element).value("14:45");
element.addEventListener("input", function (event) {
const time = event.detail.time;
console.log(time.format("hh:mm a"), time);
});
</script>
</div>
<div>
<h3>with input element</h3>
<div id="clocklet-inline-with-input-container"></div>
<input id="clocklet-inline-with-input-input">
</div>
<script>
clocklet.inline(
document.getElementById("clocklet-inline-with-input-container"),
{
input: document.getElementById("clocklet-inline-with-input-input"),
format: "_H:mm",
}
);
</script>
</div>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Changa|Frank+Ruhl+Libre:500">
<style>
.clocklet-options-1 {
font-family: Changa, sans-serif;
border-radius: 50%;
}
</style>
<input
data-clocklet="class-name: clocklet-options-1; format: h:mm AA; alignment: center; placement: top;"
placeholder="h:mm AA"
>
<style>
.clocklet-options-2 {
font-family: "Frank Ruhl Libre", serif;
font-weight: 500;
}
</style>
<input
data-clocklet="class-name: clocklet-options-2; format: hh:mm a; alignment: right; append-to: parent;"
placeholder="hh:mm a"
>
<input class="clocklet-events" data-clocklet="format: _H:_m;" maxlength="5" value=" 1:23">
<label><input class="clocklet-cancel-opening" type="checkbox">Cancel opening</label>
<label><input class="clocklet-cancel-closing" type="checkbox">Cancel closing</label>
<script>
(function () {
var inputElement = document.querySelector('.clocklet-events');
inputElement.addEventListener('clocklet.opening', function (event) {
console.log(event.type, event.target.value, event.detail.options);
if (document.querySelector('.clocklet-cancel-opening').checked) {
event.preventDefault();
}
});
inputElement.addEventListener('clocklet.opened', function (event) {
console.log(event.type, event.target.value, event.detail.options);
});
inputElement.addEventListener('clocklet.closing', function (event) {
console.log(event.type, event.target.value);
if (document.querySelector('.clocklet-cancel-closing').checked) {
event.preventDefault();
}
});
inputElement.addEventListener('clocklet.closed', function (event) {
console.log(event.type, event.target.value);
});
inputElement.addEventListener('input', function (event) {
console.log(event.type, event.target.value, event.target.value);
});
})();
</script>
<style>
.clocklet-color-example { background-color: #dce1e4; border: none; }
/* minute - dial, hand, selected tick, hovered tick */
.clocklet-color-example .clocklet-dial--minute { background-color: #fcf0e8; }
.clocklet-color-example .clocklet-hand--minute { background-color: #f5bb95; }
.clocklet-color-example .clocklet-tick--minute.clocklet-tick--selected { background-color: #f2a470; }
.clocklet-color-example.clocklet--hoverable:not(.clocklet--dragging) .clocklet-tick--minute:hover { background-color: #f5bb95; }
/* hour - dial, hand, selected tick, hovered tick */
.clocklet-color-example .clocklet-dial--hour { background-color: #e9fdf1; }
.clocklet-color-example .clocklet-hand--hour { background-color: #98f5bd; }
.clocklet-color-example .clocklet-tick--hour.clocklet-tick--selected { background-color: #44ee88; }
.clocklet-color-example.clocklet--hoverable:not(.clocklet--dragging) .clocklet-tick--hour:hover { background-color: #98f5bd; }
/* hand origin */
.clocklet-color-example .clocklet-hand-origin { background-color: #f1e369; }
/* ampm */
.clocklet-color-example .clocklet-ampm::before { background-color: #44eedd; }
.clocklet-color-example .clocklet-ampm:hover::before { background-color: #97f5ec; }
.clocklet-color-example .clocklet-ampm[data-clocklet-ampm="pm"]::before { background-color: #dd44ee; }
.clocklet-color-example .clocklet-ampm[data-clocklet-ampm="pm"]:hover::before { background-color: #eda1f6; }
</style>
<input data-clocklet="class-name: clocklet-color-example; format: hh:mm a" value="02:55 am">
<input class="clocklet-scroll-into-view" data-clocklet maxlength="5" value="01:23">
<script>
document
.querySelector('.clocklet-scroll-into-view')
.addEventListener('clocklet.opened', function (event) {
requestAnimationFrame(function () {
var inputRect = event.target.getBoundingClientRect();
var clockletRect = clocklet.root.getBoundingClientRect();
scroll({
top: document.documentElement.scrollTop
+ document.body.scrollTop
+ (event.detail.options.placement === 'top' ? clockletRect.top : inputRect.top)
- 10,
left: document.documentElement.scrollLeft
+ document.body.scrollLeft
+ clockletRect.left
- 10,
behavior: 'smooth',
});
});
});
</script>