DateTimePickerComponent is a very lightweight and dependency-free web component written in pure JavaScript

Overview

DateTimePickerComponent

GitHub package.json version

Description

DateTimePickerComponent is a very lightweight (just over 20KB) and dependency-free web component written in pure JavaScript. It supports localization, date formats, range selections and disabled dates. See the online demo.

Date picker Time picker

Motivation

Some time ago, during the development of some booking applications, I needed a date time picker that didn't require any heavy dependencies. I didn't find anything that met all my needs and browser's native implementations are currently inconsistent, so I developed mine.

Compatibility

All desktop/mobile recent browsers and IE11.

Getting started

Module environments

DateTimePickerComponent is usually delivered via npm:

npm install --save date-time-picker-component

DateTimePickerComponent exposes four different classes:

  1. DatePicker;
  2. DateTimePicker;
  3. DateRangePicker;
  4. DateTimeRangePicker.

From now on we'll refer to DatePicker and DateTimePicker as Date*Picker classes and we'll refer to DateRangePicker and DateTimeRangePicker as Date*RangePicker classes instead.

If you're using a bundler like Webpack, you'll need to import the class you need.

import 'date-time-picker-component/dist/css/date-time-picker-component.min.css';
import { DatePicker } from "date-time-picker-component/dist/js/date-time-picker-component.min";

new DatePicker( 'select_date' );

Non-module environments

DateTimePickerComponent works as well in non-module environments. You can include the necessary files from local

<link href="local-path-to/date-time-picker-component.min.css" rel="stylesheet">
<script src="local-path-to/date-time-picker-component.min.js"></script>

or from jsDelivr CDN.

<link href="https://cdn.jsdelivr.net/gh/marcellosurdi/DateTimePickerComponent/dist/css/date-time-picker-component.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/gh/marcellosurdi/DateTimePickerComponent/dist/js/date-time-picker-component.min.js"></script>

In non-module environments you must access the classes via DateTimePickerComponent object:

new DateTimePickerComponent.DatePicker( 'select_date' );

Usage

How does this component work?

When one of the classes is called with new operator like above (new DatePicker( 'select_date' );), the necessary HTML is dynamically appended to the div#select_date.

The resulting HTML for Date*Picker classes will look similar to these lines of code:

<div id="select_date" class="datetime-container">
  <div class="buttons-container">
    <button type="button" class="date start">
      <span class="week-day">mon</span>
      <span class="month-day">00</span>
      <span class="month-year"><span>jan</span><br>2000</span>
    </button>
  </div>
  <div class="picker"></div>
  <input type="hidden" name="select_date_value" class="date_output" value="">
</div>

For Date*RangePicker classes instead:

<div id="select_date" class="datetime-container fix-float">
  <div class="buttons-container fix-float">
    <button type="button" class="date start w-50">
      <span class="week-day">mon</span>
      <span class="month-day">00</span>
      <span class="month-year"><span>jan</span><br>2000</span>
    </button>
    <button type="button" class="time start w-50">
      <span class="hours">00</span>
      <span class="minutes">:00</span>
    </button>
  </div>
  <div class="picker"></div>
  <input type="hidden" name="select_date_value" class="date_output" value="">
</div>

Getting date time selection in a JS variable

As you can see, the picker is not tied to an input text, so the selected date is always returned to the value attribute of the input.date_output, according to settings.date_output property. So we simply have to get the value of input.date_output inside the top level div.

new DatePicker( 'select_date' );

// your code...

// Retrieves the date time selection and puts it in the 'selection' variable
let selection = document.querySelector( 'div#select_date input.date_output' ).value;

See the settings section below to know supported date time formats.

Date*Picker classes

DatePicker and DateTimePicker classes allow to select a date or a date/time respectively, see the online demo.

Params

Property Type Default Description
id {string} None Id of the div element where to append the component. An error is thrown if no value or invalid value is passed
[settings] {object} {} Object with user defined settings

See the settings section for more details.

Example

Here a JavaScript example:

import 'date-time-picker-component/dist/css/date-time-picker-component.min.css';
import { DatePicker } from "date-time-picker-component/dist/js/date-time-picker-component.min";

new DatePicker( 'select_date', {
  first_date: "2030-01-02",
  start_date: "2030-01-05",
  last_date: new Date( 2030, 0, 29 ),
  first_day_no: 1,
  date_output: "timestamp",
  styles: {
    active_background: '#e34c26',
    active_color: '#fff'
  }
} );

And the corresponding HTML:

<body>
  <div id="select_date"></div>
</body>

Date*RangePicker classes

DateRangePicker and DateTimeRangePicker classes allow to select a date range or a date/time range respectively, see the online demo.

Params

Property Type Default Description
start_id {string} None Id of the start date div element. An error is thrown if no value or invalid value is passed
end_id {string} None Id of the end date div element. An error is thrown if no value or invalid value is passed
[settings] {object} {} Object with user defined settings

See the settings section for more details.

Example

Here a JavaScript example:

import 'date-time-picker-component/dist/css/date-time-picker-component.min.css';
import { DateTimeRangePicker } from "date-time-picker-component/dist/js/date-time-picker-component.min";

new DateTimeRangePicker( 'start_date_time', 'end_date_time', {
  first_date: "2030-01-02T10:30:00",
  start_date: "2030-01-05T16:00:00",
  end_date: "2030-01-06T18:00:00",
  last_date: new Date( 2030, 0, 29, 14, 0 ),
  first_day_no: 1,
  date_output: "timestamp",
  styles: {
    active_background: '#e34c26',
    active_color: '#fff',
    inactive_background: '#0366d9',
    inactive_color: '#fff'
  },
    min_range_hours: 18
} );

And the corresponding HTML:

<body>
  <div id="start_date"></div>
  <div id="end_date"></div>
</body>

Settings

All classes support these properties in settings object. All *_date properties can be a date string (in ISO format) or a date object.

Property Type Default Description
first_date {Date|string} Current date First selectable date.
start_date {Date|string} One day more than current date Start selected date
last_date {Date|string} One year more than start_date Last selectable date
first_day_no {number} 0 (Sunday) Day the week must start with. Accepted range values are 0-6 where 0 means Sunday, 1 means Monday and so on
date_output {string} "short_ISO" or "full_ISO" The date format returned to the value attribute of input.date_output. Accepted values are short_ISO (default for Date* classes, e.g. "2030-01-05"), full_ISO (default for DateTime* classes, e.g. "2021-07-16T09:30:00") and timestamp (without milliseconds).
l10n {object} Object with English strings Object with strings for translation
styles {object} {} Object with custom styles

Only the Date*RangePicker classes also support these properties:

Property Type Default Description
end_date {Date|string} One day more than start_date End selected date
min_range_hours {number} 1 The minimum range expressed in hours that must elapse between start_date and end_date

Rounding minutes (since 1.1.0)

With DateTimePicker and DateTimeRangePicker classes it also make sense to set the settings.round_to property.

Property Type Default Description
round_to {number} false Value to round minutes of time picker. Accepted values are 1, 5, 10, 15, 20, 30

If you don't set this property you'll see the time picker exactly as the 1.0.x version (see example 4). If you set this property you'll get a time picker with two select elements, one for the hours and one for the minutes (see example 6). Minutes will be rounded to the round_to value and his multiples. For instance with round_to set to 15, the options in the select element will be 00, 15, 30, 45; with round_to set to 20, the options will be 00, 20, 40 and so on. 1 (or an unaccepted value) will show all values from 00 to 59.

new DateTimeRangePicker( 'start_date_time', 'end_date_time', {
  first_date: "2030-01-02T10:30:00",
  start_date: "2030-01-05T16:00:00",
  end_date: "2030-01-06T18:00:00",
  last_date: new Date( 2030, 0, 29, 14, 0 ),
  first_day_no: 1,
  round_to: 5, // Enables the time picker with two select elements
  date_output: "timestamp",
  styles: {
    active_background: '#e34c26',
    active_color: '#fff',
    inactive_background: '#0366d9',
    inactive_color: '#fff'
  },
    min_range_hours: 18
} );

Alternative time picker

Localization (i10n)

All classes support the settings.l10n property to localize the component in your language. You just have to pass an object like the one below to that property.

let it = {
  'jan':'Gen',
  'feb':'Feb',
  'mar':'Mar',
  'apr':'Apr',
  'may':'Mag',
  'jun':'Giu',
  'jul':'Lug',
  'aug':'Ago',
  'sep':'Set',
  'oct':'Ott',
  'nov':'Nov',
  'dec':'Dic',
  'jan_':'Gennaio',
  'feb_':'Febbraio',
  'mar_':'Marzo',
  'apr_':'Aprile',
  'may_':'Maggio',
  'jun_':'Giugno',
  'jul_':'Luglio',
  'aug_':'Agosto',
  'sep_':'Settembre',
  'oct_':'Ottobre',
  'nov_':'Novembre',
  'dec_':'Dicembre',
  'mon':'Lun',
  'tue':'Mar',
  'wed':'Mer',
  'thu':'Gio',
  'fri':'Ven',
  'sat':'Sab',
  'sun':'Dom',
  'mon_':'Lunedì',
  'tue_':'Martedì',
  'wed_':'Mercoledì',
  'thu_':'Giovedì',
  'fri_':'Venerdì',
  'sat_':'Sabato',
  'sun_':'Domenica',
  'done':'Imposta' // @since 1.1.0
};

new DatePicker( 'select_date', {
    l10n: it,
  }
);

Styles customization

All classes support the settings.styles property for styles customization.

// Date*Picker classes
new DatePicker( 'select_date', {
  styles: {
    active_background: '#e34c26',
    active_color: '#fff'
  }
} );

// Date*RangePicker classes
new DateTimeRangePicker( 'start_date_time', 'end_date_time', {
  styles: {
    active_background: '#e34c26',
    active_color: '#fff',
    inactive_background: '#0366d9',
    inactive_color: '#fff'
  },
} );

All you need to do is to use active_background, active_color, inactive_background and inactive_color properties like above. Active colors denote the clicked buttons and the day/hour you're setting, inactive colors the other day in the range. Date*Picker classes of course don't support inactive_* properties because there isn't a range.

Color scheme

Maintaining state

To set date time default or to retain the date time selection after a page reload due, for instance, to a failed validation, you can add by yourself the input.date_output inside the top level div in this way:

<body>
  <!-- Date*Picker classes -->
  <div id="select_date">
    <input type="hidden" name="my_value" class="date_output" value="2030-05-22">
  </div>

  <!-- Date*RangePicker classes -->
  <div id="start_date">
    <!-- Overwrites start_date -->
    <input type="hidden" name="my_value" class="date_output" value="2030-05-22">
  </div>
  <div id="end_date">
    <!-- Overwrites end_date -->
    <input type="hidden" name="my_value" class="date_output" value="2030-05-22T10:00:00">
  </div>
</body>

The component will detect hidden input fields (it will no longer add them), and use the content of their value attribute as default. This may be useful if you are a server side developer and you can't access separate js files of your application. In this case the content of name attribute is totally up to you, otherwise it will be top_level_div_id + '_value'.

Build

To compile DateTimePickerComponent by yourself, make sure that you have Node.js installed, then:

  1. Fork and clone the GitHub repository.
  2. From the command line go to the local DateTimePickerComponent folder.
  3. Run npm install and wait for the necessary modules installation. Webpack will be installed, look at the other dev dependencies in the package.json file.
  4. The npm run dev command opens a new Chrome window for developing purposes, npm run build compiles in dist folder.

That's it!

Do you use DateTimePickerComponent?

Let me know with a link if you've used DateTimePickerComponent in some interesting way, or on a popular site.

Links

  1. Online demo
  2. Source code documentation
  3. Changelog
You might also like...

A low-feature, dependency-free and performant test runner inspired by Rust and Deno

minitest A low-feature, dependency-free and performant test runner inspired by Rust and Deno Simplicity: Use the mt test runner with the test function

Nov 12, 2022

Jsonup - This is a zero dependency compile-time JSON parser written in TypeScript

jsonup This is a zero dependency compile-time JSON parser written in TypeScript.

Dec 8, 2022

DOM ViewModel - A thin, fast, dependency-free vdom view layer

DOM ViewModel - A thin, fast, dependency-free vdom view layer

domvm (DOM ViewModel) A thin, fast, dependency-free vdom view layer (MIT Licensed) Introduction domvm is a flexible, pure-js view layer for building h

Dec 8, 2022

Small, typed, dependency free tool to round corners of 2d-polygon provided by an array of { x, y } points.

Small, typed, dependency free tool to round corners of 2d-polygon provided by an array of { x, y } points.

round-polygon Small, typed, dependency-free tool to round corners of 2d-polygon provided by an array of { x, y } points. The algorithm prevents roundi

Nov 26, 2022

A dependency-free Vanilla JS Accordion Menu Nested

🚀 A dependency-free Vanilla JS Accordion Menu Nested No dependencies, no automation build tools. Copy/paste and ready to use. CSS and JS are inlined

Dec 18, 2022

Dependency-free implementation of zoom.js (no jQuery or Bootstrap)

Dependency-free implementation of zoom.js (no jQuery or Bootstrap)

ZOOM.JS Repo status Nov 2020: Maintained, but bug fixes only. No new features currently, please. There may eventually be a new major version with new

Jan 3, 2023

Responsive tabs-to-accordion script without jQuery, written using pure JavaScript

vanilla-tabs Responsive tabs-to-accordion script without jQuery, written using pure JavaScript Author Dmytro Kudleichuk LinkedIn GitHub Online Demo Se

Dec 20, 2022

Snowfall effect written in pure JavaScript. No additional libraries, no dependencies. Works in every modern browser.

pureSnow.js Snow falling slowly on a winter night. Probably the most calming and peaceful snowfall effect written in pure JS/CSS. (No SCSS). Inspired

Dec 29, 2022

A simple color picker application written in pure JavaScript, for modern browsers.

A simple color picker application written in pure JavaScript, for modern browsers.

Color Picker A simple color picker application written in pure JavaScript, for modern browsers. Has support for touch events. Touchy… touchy… Demo and

Dec 14, 2022
Comments
  • Option to disable some times on specific dates

    Option to disable some times on specific dates

    Is it possible to deactivate some hours on a specific date? For example: Every hour can be booked a service. If on 27-04-2022 at 15:00 is already booked, would be great the possibility to disable 27-04-2022 at 15:00 in order to not let it be selected again.

    enhancement 
    opened by litos10 2
  • Dynamically change date

    Dynamically change date

    I want to change the date dynamically with JS. I can't for the life of me figure out how to do this.

    I read another issue and the author seems to be asking for a similar thing.

    Again, I don't want to change the date by having the user select it, I want to change the date by running a function.

    calendar = new DateTimePicker("select_datetime", {
              // settings
          },
        });
    
    let date = Date.now();
    calendar.changeDate(date)   <---- simple style update.
    

    Sorry if this is doable and right in front of my face, but I can't figure it out. Thanks!

    enhancement 
    opened by wktdev 1
  • Modifications

    Modifications

    Add the capability to select month directly when hit over the month text in calendar view as well can select the year between a years range hitting the year in calendar view.

    enhancement 
    opened by yulier-molina 2
  • target for event listeners

    target for event listeners

    I didn't see this in the documentation: is there a preferred spot for registering for changes in the selected date? The "type" on the input is "hidden" and can't get date changes to trigger.

    enhancement 
    opened by imaginethatok 8
Releases(v1.1.2)
Owner
null
Fast and lightweight dependency-free vanilla JavaScript polyfill for native lazy loading / the awesome loading='lazy'-attribute.

loading="lazy" attribute polyfill Fast and lightweight vanilla JavaScript polyfill for native lazy loading, meaning the behaviour to load elements rig

Maximilian Franzke 571 Dec 30, 2022
a lightweight, dependency-free JavaScript plugin which makes a HTML table interactive

JSTable The JSTable is a lightweight, dependency-free JavaScript plugin which makes a HTML table interactive. The plugin is similar to the jQuery data

null 63 Oct 20, 2022
The JSTable is a lightweight, dependency-free JavaScript plugin which makes a HTML table interactive

The JSTable is a lightweight, dependency-free JavaScript plugin which makes a HTML table interactive. The plugin is similar to the jQuery data

null 63 Oct 20, 2022
EggyJS is a Javascript micro Library for simple, lightweight toast popups focused on being dependency-less, lightweight, quick and efficient.

EggyJS EggyJS is a Javascript micro Library for simple, lightweight toast popups. The goal of this library was to create something that meets the foll

Sam 10 Jan 8, 2023
Lightweight vanilla js modal component (just 2kb) , pure javascript Modal

Lightweight vanilla js modal component (just 2kb) pure javascript Modal , This is just 2kb Lightweight vanilla js modal component with zero dependenci

Salah Eddine Lalami 12 Dec 12, 2022
An exercise in building a very minimal (and very stupid) in-memory SQL-like database for educational purposes.

Stupid Database This is an exercise in building a very minimal (and very stupid) in-memory SQL-like database for educational purposes. None of this co

Fabio Akita 196 Dec 20, 2022
A Very Good Documentation Site created by the Very Good Ventures Team 🦄

Very Good Docs Site Developed with ?? by Very Good Ventures ?? A Very Good Docs Site created by the Very Good Ventures Team. Generated by the Very Goo

Very Good Open Source 8 Nov 2, 2022
This is a dependency-free easy-to-use vanilla JavaScript addon allowing you to create HTML currency inputs with various different currencies and formattings.

intl-currency-input This is a dependency-free easy-to-use vanilla JavaScript addon allowing you to create HTML currency inputs with various different

null 6 Jan 4, 2023
A dependency-free JavaScript library for creating discreet pop-up notifications.

Polipop A dependency-free JavaScript library for creating discreet pop-up notifications. Demo See demo at minitek.github.io/polipop/. Documentation Se

Minitek 8 Aug 15, 2022
A very simple JavaScript library written in vanilla js for scrambling text.

Scrambling Text A very simple JavaScript library written in vanilla js for scrambling text. Demo Page Table of Contents Installation Examples Basic Ex

sogoagain 10 Dec 7, 2022