Skip to content

Wernfried/daterangepicker

 
 

Repository files navigation

Date Range Picker

Daterangepicker Exsample

This date range picker component creates a dropdown menu from which a user can select a range of dates.

Features include limiting the selectable date range, localizable strings and date formats, a single date picker mode, a time picker, and predefined date ranges.

Above samples are based on the original repository from Dan Grossman. New features from this fork are not available in these samples.

Basic usage

Global import with <script> tags

<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/luxon@3.5.0/build/global/luxon.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.3.7/dist/global/daterangepicker.min.js"></script>
<link type="text/css" href="https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.3.7/css/daterangepicker.min.css" rel="stylesheet" />

<input type="text" id="picker" />

<script type="text/javascript">
   const DateTime = luxon.DateTime;
   DateRangePicker.daterangepicker('#picker', {
      startDate: DateTime.now().plus({day: 1})
   }, (start, end) => {
      console.log(`Selected range: ${start.toString()} to ${end.toString()}`)
   });
</script>

ESM Imports

<script type="importmap">
{
   "imports": {
      "luxon": "https://cdn.jsdelivr.net/npm/luxon@3.7.2/+esm",
      "daterangepicker": "https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.3.7/+esm"
   }
}
</script>
<link type="text/css" href="https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.3.7/css/daterangepicker.min.css" rel="stylesheet" />

<input type="text" id="picker" />

<script type="module">
   import { DateTime } from 'luxon';
   import { daterangepicker } from 'daterangepicker';

   daterangepicker('#picker', {
      startDate: DateTime.now().plus({day: 1})
   }, (start, end) => {
      console.log(`Selected range: ${start.toString()} to ${end.toString()}`)
   });
</script>

Style with Bulma

<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/luxon@3.5.0/build/global/luxon.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.3.7/dist/global/daterangepicker.min.js"></script>
<link type="text/css" href="https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css" rel="stylesheet" />
<link type="text/css" href="https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.3.7/css/daterangepicker.bulma.min.css" rel="stylesheet" />

<input type="text" id="picker" />

<script type="text/javascript">
   const DateTime = luxon.DateTime;
   DateRangePicker.daterangepicker('#picker', {
      startDate: DateTime.now().plus({day: 1})
   });
</script>

Use of data-* attributes

<input type="text" id="picker" 
   data-start-date="2026-02-01" 
   data-end-date="2026-02-20" 
   data-show-week-numbers="true" />

<script>
   const options = {timePicker: true};
   DateRangePicker.daterangepicker('#picker', options);
</script>

See HTML5 data-* Attributes
Values in options of daterangepicker(el, options) take precedence over data-* attributes.

Access the DateRangePicker Instance

<input type="text" id="picker" />

<script type="module">
   import {daterangepicker, getDateRangePicker} from 'daterangepicker'; // or global import with <script> tag
   
   const input = daterangepicker('#picker', {}); // returns the mutated <input> HTMLElement
   // or daterangepicker(document.querySelector('#picker'), {})

   const drp = getDateRangePicker('#picker');
   // or DateRangePicker.getDateRangePicker('#picker'); if imported globally with <script> tag

   console.log( drp.startDate.toString()) // prints the selected startDate
   console.log( drp === input._daterangepicker) // prints 'true'
   console.log( drp.element === input) // prints 'true'
   console.log( document.querySelector('#picker') === input) // prints 'true'
</script>

Upgrade from daterangepicker version 4.x -> 5.x

In version 5.x jQuery dependency has been removed. Version 4.x is available at branch 4.x-jQuery but new features will not added anymore to this branch.
Unlesss you work with Events, you should not face any difference between version 4.x and 5.x. Initialisation with jQuery is supported in version 5.x

<script type="text/javascript" src="https://cdn.jsdelivr.net/jquery/latest/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/luxon@3.5.0/build/global/luxon.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.3.7/dist/global/daterangepicker.min.js"></script>
<link type="text/css" href="https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.3.7/css/daterangepicker.min.css" rel="stylesheet" />

<input type="text" id="picker" />

<script type="text/javascript">
   const DateTime = luxon.DateTime;
   
   // if you like to work with jQuery in version 5.x
   $(function() {
      $('#picker').daterangepicker({
         startDate: DateTime.now().plus({day: 1})
      });
   }).on('beforeHide', (ev) => {
      console.log(ev.originalEvent.picker.startDate.toString());
      ev.preventDefault(); // -> do not hide the picker
   });
</script>

In case you work with Events there are a few minor changes:

// version 4.x - with jQuery
$('#picker').daterangepicker({
   startDate: DateTime.now(),
   // allow only dates from current year
   minDate: DateTime.now().startOf('year'),
   manDate: DateTime.now().endOf('year'),
   singleDatePicker: true
}).on('violate.daterangepicker', (ev, picker, result, newDate) => {
   newDate.startDate = DateTime.now().minus({ days: 3 }).startOf('day');
   return true;
}).on('show.daterangepicker', (ev, picker) => {
   console.log('Show the picker')
}).on('beforeHide.daterangepicker', (ev, picker) => {
   console.log(picker.startDate.toString());
   return true; // -> do not hide the picker
});

// version 5.x - without jQuery
const input = daterangepicker('#picker', { // or DateRangePicker.daterangepicker('#picker', ...
   startDate: DateTime.now(),
   // allow only dates from current year
   minDate: DateTime.now().startOf('year'),
   manDate: DateTime.now().endOf('year'),
   singleDatePicker: true
});

input.addEventListener('violate', (ev) => {
   ev.newDate.startDate = DateTime.now().minus({ days: 3 }).startOf('day');
   ev.preventDefault();
});
input.addEventListener('show', (ev) => {
   console.log('Show the picker')
});
input.addEventListener('beforeHide', (ev) => {
   console.log(ev.picker.startDate.toString());
   ev.preventDefault(); // -> do not hide the picker
});

Examples

Option ranges

ranges: {
   'Today': [DateTime.now().startOf('day'), DateTime.now().endOf('day')],
   'Yesterday': [DateTime.now().startOf('day').minus({day: 1}), DateTime.now().endOf('day').minus({day: 1})],
   'Last 7 Days': ['2025-03-01', '2025-03-07'],
   'Last 30 Days': [new Date(new Date - 1000*60*60*24*30), new Date()],
   'This Month': [DateTime.now().startOf('month'), DateTime.now().endOf('month')],
   'Last Month': [DateTime.now().minus({month: 1}).startOf('month'), DateTime.now().minus({month: 1}).endOf('month')]
},
alwaysShowCalendars: true

Option isInvalidDate

isInvalidDate: function(date) {
   return date.isWeekend; // see https://moment.github.io/luxon/api-docs/index.html#datetimeisweekend
}

Option isInvalidTime

isInvalidTime: (time, side, unit) => {   
   if (unit == 'hour') {
      return time.hour >= 10 && time.hour <= 14; // Works also with 12-hour clock      
   } else {
      return false;
   }
}

Option isCustomDate

.daterangepicker-bank-day {
  color: red;
}
.daterangepicker-weekend-day {
  color: blue;
}

isCustomDate: function(date) {
   if (date.isWeekend)
      return 'daterangepicker-weekend-day';

   const yyyy = date.year;
   let bankDays = [
      DateTime.fromObject({ year: yyyy, month: 1, day: 1 }), // New year
      DateTime.fromObject({ year: yyyy, month: 7, day: 4 }), // Independence Day
      DateTime.fromObject({ year: yyyy, month: 12, day: 25 }) // Christmas Day
   ];
   return bankDays.some(x => x.hasSame(date, 'day')) ? 'daterangepicker-bank-day' : '';
}

Features

Compared to inital repository, this fork added following features and changes:

  • Replaced moment by luxon (see differences below)
  • Added option weekendClasses, weekendDayClasses, todayClasses to highlight weekend days or today, respectively
  • Added option timePickerStepSize to succeed options timePickerIncrement and timePickerSeconds
  • Added events dateChange and timeChange emitted when user clicks on a date/time
  • Added event beforeHide enables you to keep the picker visible after click on Apply or Cancel button.
  • Added event beforeRenderTimePicker and beforeRenderCalendar emitted before elements are rendered
  • Added event violate emitted when user input is not valid
  • Added method setRange(startDate, endDate) to combine setStartDate(startDate) and setEndDate(endDate)
  • Added option minSpan similar to maxSpan
  • Added option isInvalidTime similar to isInvalidDate
  • Added option altInput and altFormat to provide an alternative output element for selected date value
  • Added option onOutsideClick where you can define whether picker shall apply or revert selected value
  • Added option initalMonth to show datepicker without an initial date
  • Added option singleMonthView to show single month calendar, useful for shorter ranges
  • Added option showOnClick and button to provide better control when DateRangePicker pops up
  • Better validation of input parameters, errors are logged to console
  • Highlight range in calendar when hovering over pre-defined ranges
  • Option autoUpdateInput defines whether the attached <input> element is updated when the user clicks on a date value.
    In original daterangepicker this parameter defines whether the <input> is updated when the user clicks on Apply button.
  • Added option locale.durationFormat to show customized label for selected duration, e.g. '4 Days, 6 Hours, 30 Minutes'
  • Support styling with 3rd party CSS Frameworks. Currently only Bulma is supported
    but other frameworks may be added in future releases
  • ESM Module Import
  • Jest unit testing
  • Removed dependency from jQuery
  • ... and maybe some new bugs 😉

Localization

All date values are based on luxon which provides great support for localization. Instead of providing date format, weekdays, month names, etc. manually it is usually easier to set the default locale like this:

const Settings = luxon.Settings;
Settings.defaultLocale = 'fr-CA'
daterangepicker('#picker', {
   timePicker: true
};

instead of

daterangepicker('#picker', {
   timePicker: true,
   timePicker24Hour: true,
   locale: {
      format: 'yyyyy-M-d H h m',
      daysOfWeek: [ 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.', 'dim.' ],
      monthNames: [ "janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre" ],
      firstDay: 7
   }
};

Style and themes

You can style this daterangepicker with Bulma CSS Framework. Light and dark theme is supported:

Bulma dark example

Bulma light example

Methods

Available methods are listed in detail at API Documentation. You will mainly use

all other methods are used rarely.

Differences between moment and luxon library

This table lists a few important differences between datarangepicker using moment and luxon. Check them carefully when you migrate from older daterangepicker.

Parameter moment luxon
locale.daysOfWeek [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ] [ "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" ]
locale.firstDay 0-6 (Sunday to Saturday) 1 for Monday through 7 for Sunday
to ISO-8601 String toISOString() toISO()
to Date Object toDate() toJSDate()
from ISO-8601 String moment(...) DateIme.fromISO(...)
from Date Object moment(...) DateIme.fromJSDate(...)
current day moment() DateTime.now()
format to string format(...) toFormat(...)
format tokens 'YYYY-MM-DD' 'yyyy-MM-dd'

License

The MIT License (MIT)

Copyright (c) 2012-2019 Dan Grossman
Copyright (c) 2025 Wernfried Domscheit

Licensed under the MIT license.

API Documentation

API Documentation

Options

Options for DateRangePicker

Kind: global typedef
Properties

Name Type Default Description
parentEl string | HTMLElement "body" Document querySelector or HTMLElement of the parent element that the DateRangePicker will be added to
startDate DateTime | Date | string | null Default: DateTime.now().startOf('day')
The beginning date of the initially selected date range.
Must be a luxon.DateTime or Date or string according to ISO-8601 or a string matching locale.format.
Date value is rounded to match option timePickerStepSize
Option isInvalidDate and isInvalidTime are not evaluated, you may set date/time which is not selectable in calendar.
If the date does not fall into minDate and maxDate then date is shifted and a warning is written to console.
Use startDate: null to show calendar without an initial selected date.
endDate DateTime | Date | string Default: DateTime.now().endOf('day')
The end date of the initially selected date range.
Must be a luxon.DateTime or Date or string according to ISO-8601 or a string matching locale.format.
Date value is rounded to match option timePickerStepSize
Option isInvalidDate, isInvalidTime and minSpan, maxSpan are not evaluated, you may set date/time which is not selectable in calendar.
If the date does not fall into minDate and maxDate then date is shifted and a warning is written to console.
minDate DateTime | Date | string | null The earliest date a user may select or null for no limit.
Must be a luxon.DateTime or Date or string according to ISO-8601 or a string matching locale.format.
maxDate DateTime | Date | string | null The latest date a user may select or null for no limit.
Must be a luxon.DateTime or Date or string according to ISO-8601 or a string matching locale.format.
minSpan Duration | string | number | null The minimum span between the selected start and end dates.
Must be a luxon.Duration or number of seconds or a string according to ISO-8601 duration.
Ignored when singleDatePicker: true
maxSpan Duration | string | number | null The maximum span between the selected start and end dates.
Must be a luxon.Duration or number of seconds or a string according to ISO-8601 duration.
Ignored when singleDatePicker: true
defaultSpan Duration | string | number | null The span which is used when endDate is automatically updated due to wrong user input
Must be a luxon.Duration or number of seconds or a string according to ISO-8601 duration.
Ignored when singleDatePicker: true. Not relevant if minSpan: null
initialMonth DateTime | Date | string | null Default: DateTime.now().startOf('month')
The inital month to be shown. Only relevant for startDate: null. Be aware, the attached <input> element must also be empty.
Must be a luxon.DateTime or Date or string according to ISO-8601 or a string matching locale.format.
Works only with timePicker: false
autoApply boolean false Hide the Apply and Cancel buttons, and automatically apply a new date range as soon as two dates are clicked.
Only useful when timePicker: false
singleDatePicker boolean false Show only a single calendar to choose one date, instead of a range picker with two calendars.
If true, then endDate is always null.
singleMonthView boolean false Show only a single month calendar, useful when selected ranges are usually short
or for smaller viewports like mobile devices.
Ignored for singleDatePicker: true.
showDropdowns boolean false Show year and month select boxes above calendars to jump to a specific month and year
minYear number Default: DateTime.now().minus({year:100}).year
The minimum year shown in the dropdowns when showDropdowns: true
maxYear number Default: DateTime.now().plus({year:100}).year
The maximum year shown in the dropdowns when showDropdowns: true
showWeekNumbers boolean false Show localized week numbers at the start of each week on the calendars
showISOWeekNumbers boolean false Show ISO week numbers at the start of each week on the calendars.
Takes precedence over localized showWeekNumbers
button string | external:HTMLButtonElement null A dedicated element to show the DateRangePicker on click.
Main reason of this option is to prevent hide/flicker of the picker on outsideClick()
showOnClick boolean true Shows/toggle the DateRangePicker on click or focus at element.
You may want to set it to false only when option button is provided or when you use show() programmatically.
timePicker boolean false Adds select boxes to choose times in addition to dates
timePicker24Hour boolean Use 24-hour instead of 12-hour times, removing the AM/PM selection.
Default is derived from current locale Intl.DateTimeFormat.resolvedOptions.hour12.
timePickerStepSize Duration | string | number Default: Duration.fromObject({minutes:1})
Set the time picker step size.
Must be a luxon.Duration or the number of seconds or a string according to ISO-8601 duration.
Valid values are 1,2,3,4,5,6,10,12,15,20,30 for Duration.fromObject({seconds: ...}) and Duration.fromObject({minutes: ...}) and 1,2,3,4,6,(8,12) for Duration.fromObject({hours: ...}).
Duration must be greater than minSpan and smaller than maxSpan.
For example timePickerStepSize: 600 will disable time picker seconds and time picker minutes are set to step size of 10 Minutes.
autoUpdateInput boolean true Indicates whether the DateRangePicker should instantly update the value of the attached <input> element when the selected dates change.
The <input> element will be always updated on Apply and reverted when user clicks on Cancel.
onOutsideClick string "apply" Defines what picker shall do when user clicks outside the calendar. 'apply' or 'cancel'. Event onOutsideClick is always emitted.
linkedCalendars boolean true When enabled, the two calendars displayed will always be for two sequential months (i.e. January and February), and both will be advanced when clicking the left or right arrows above the calendars.
When disabled, the two calendars can be individually advanced and display any month/year
isInvalidDate function false A function that is passed each date in the two calendars before they are displayed,
and may return true or false to indicate whether that date should be available for selection or not.
Signature: isInvalidDate(date)
isInvalidTime function false A function that is passed each hour/minute/second/am-pm in the two calendars before they are displayed,
and may return true or false to indicate whether that date should be available for selection or not.
Signature: isInvalidTime(time, side, unit)
side is 'start' or 'end' or null for singleDatePicker: true
unit is 'hour', 'minute', 'second' or 'ampm'
Hours are always given as 24-hour clock
Ensure that your function returns false for at least one item. Otherwise the calender is not rendered.
isCustomDate function false A function that is passed each date in the two calendars before they are displayed, and may return a string or array of CSS class names to apply to that date's calendar cell.
Signature: isCustomDate(date)
altInput string | Array | HTMLInputElement null A Document querySelector
string or HTMLElement for an alternative output (typically hidden) <input> element. Uses altFormat to format the value.
Must be a single string/HTMLElement for singleDatePicker: true or an array of two strings or HTMLElement for singleDatePicker: false
Example: ['#start', '#end']
altFormat function | string The output format used for altInput.
Default: ISO-8601 basic format without time zone, precisison is derived from timePicker and timePickerStepSize
Example yyyyMMdd'T'HHmm for timePicker=true and display of Minutes
If defined, either a string used with Format tokens or a function.
Examples: "yyyy:MM:dd'T'HH:mm",
(date) => date.toUnixInteger()
applyButtonClasses string "btn-primary" CSS class names that will be added only to the apply button
cancelButtonClasses string "btn-default" CSS class names that will be added only to the cancel button
buttonClasses string Default: 'btn btn-sm'
CSS class names that will be added to both the apply and cancel buttons.
weekendClasses string "weekend" CSS class names that will be used to highlight weekend days.
Use null or empty string if you don't like to highlight weekend days.
weekendDayClasses string "weekend-day" CSS class names that will be used to highlight weekend day names.
Weekend days are evaluated by Info.getWeekendWeekdays and depend on current locale settings. Use null or empty string if you don't like to highlight weekend day names.
todayClasses string "today" CSS class names that will be used to highlight the current day.
Use null or empty string if you don't like to highlight the current day.
opens string "right" Whether the picker appears aligned to the left, to the right, or centered under the HTML element it's attached to.
'left' | 'right' | 'center'
drops string "down" Whether the picker appears below or above the HTML element it's attached to.
'down' | 'up' | 'auto'
ranges object {} Set predefined date Ranges the user can select from. Each key is the label for the range, and its value an array with two dates representing the bounds of the range.
showCustomRangeLabel boolean true Displays "Custom Range" at the end of the list of predefined Ranges, when the ranges option is used.
This option will be highlighted whenever the current date range selection does not match one of the predefined ranges.
Clicking it will display the calendars to select a new range.
alwaysShowCalendars boolean false Normally, if you use the ranges option to specify pre-defined date ranges, calendars for choosing a custom date range are not shown until the user clicks "Custom Range".
When this option is set to true, the calendars for choosing a custom date range are always shown instead.
showLabel boolean Shows selected range next to Apply buttons.
Defaults to false if anchor element is <input type="text">, otherwise true
locale object {} Allows you to provide localized strings for buttons and labels, customize the date format, and change the first day of week for the calendars.
locale.direction string "ltr" Direction of reading, 'ltr' or 'rtl'
locale.format object | string Default: DateTime.DATE_SHORT or DateTime.DATETIME_SHORT when timePicker: true
Date formats. Either given as string, see Format Tokens or an object according to Intl.DateTimeFormat
I recommend to use the luxon Presets.
locale.separator string Defaut: ' - '
Separator for start and end time
locale.weekLabel string "W" Label for week numbers
locale.daysOfWeek Array Default: luxon.Info.weekdays('short')
Array with weekday names, from Monday to Sunday
locale.monthNames Array Default: luxon.Info.months('long')
Array with month names
locale.firstDay number Default: luxon.Info.getStartOfWeek()
First day of the week, 1 for Monday through 7 for Sunday
locale.applyLabel string "Apply" Label of Apply Button
locale.cancelLabel string "Cancel" Label of Cancel Button
locale.customRangeLabel string "Custom" Range - Title for custom ranges
locale.durationFormat object | string | function {} Format a custom label for selected duration, for example '5 Days, 12 Hours'.
Define the format either as string, see Duration.toFormat - Format Tokens or an object according to Intl.NumberFormat, see Duration.toHuamn.
Or custom function as (startDate, endDate) => {}

About

JavaScript Date Range, Date and Time Picker Component

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

  • JavaScript 66.1%
  • HTML 26.7%
  • CSS 7.2%