Datepair.js

A javascript plugin for intelligently selecting date and time ranges
inspired by Google Calendar.

Use this plugin to link date and time inputs when you need to select ranges.
No dependencies, with optional support for jQuery/Zepto.

Basic Example

Datepair.js doesn't include any date or time picker widgets, but it's preconfigured to work with jquery-timepicker and Bootstrap Datepicker. Include input widgets as you normally would, and then use Datepair.js to link them.

to

<p id="basicExample">
    <input type="text" class="date start" />
    <input type="text" class="time start" /> to
    <input type="text" class="time end" />
    <input type="text" class="date end" />
</p>

<!-- include input widgets; this is independent of Datepair.js -->
<link rel="styleshee" type="text/css" href="jquery.timepicker.css" />
<link rel="stylesheet" type="text/css" href="bootstrap-datepicker.css" />
<script type="text/javascript" src="bootstrap-datepicker.js"></script>
<script type="text/javascript" src="jquery.timepicker.js"></script>

<script type="text/javascript" src="datepair.js"></script>
<script>
    // initialize input widgets first
    $('#basicExample .time').timepicker({
        'showDuration': true,
        'timeFormat': 'g:ia'
    });

    $('#basicExample .date').datepicker({
        'format': 'm/d/yyyy',
        'autoclose': true
    });

    // initialize datepair
    var basicExampleEl = document.getElementById('basicExample');
    var datepair = new Datepair(basicExampleEl);
</script>
            

jQuery Example

Include the optional jquery.datepicker.js file to interact with Datepair.js with a jQuery interface.

to

<p id="jqueryExample">
    <input type="text" class="date start" />
    <input type="text" class="time start" /> to
    <input type="text" class="time end" />
    <input type="text" class="date end" />
</p>

<script type="text/javascript" src="datepair.js"></script>
<script type="text/javascript" src="jquery.datepair.js"></script>
<script>
    // initialize input widgets first
    $('#jqueryExample .time').timepicker({
        'showDuration': true,
        'timeFormat': 'g:ia'
    });

    $('#jqueryExample .date').datepicker({
        'format': 'm/d/yyyy',
        'autoclose': true
    });

    // initialize datepair
    $('#jqueryExample').datepair();
</script>
            

Date-only Example

You can use datepair with just dates, or just times.

to

to

// HTML not shown for brevity

$('#timeOnlyExample .time').timepicker({
    'showDuration': true,
    'timeFormat': 'g:ia'
});

var timeOnlyExampleEl = document.getElementById('timeOnlyExample');
var timeOnlyDatepair = new Datepair(timeOnlyExampleEl);

$('#dateOnlyExample .date').datepicker({
    'format': 'yyyy-m-d',
    'autoclose': true
});

var dateOnlyExampleEl = document.getElementById('dateOnlyExample');
var dateOnlyDatepair = new Datepair(dateOnlyExampleEl);
            

Default Delta Example

Datepair can automatically set the other input when a first value is selected.

to

// HTML not shown for brevity

var defaultDeltaExampleEl = document.getElementById('defaultDeltaExample');
var defaultDeltaDatepair = new Datepair(defaultDeltaExampleEl, {
    'defaultDateDelta': 1,      // days
    'defaultTimeDelta': 7200000 // milliseconds
});
            

Alternate UI Widgets Example

jquery-datepair is widget agnostic and can work with any date and time pickers. Here's an example with jQuery.ptTimeSelect and Pikaday.

to

<p id="alternateUiWidgetsExample">
    <input type="text" class="date start" />
    <input type="text" class="time start" /> to<br />
    <input type="text" class="date end" />
    <input type="text" class="time end" />
</p>
<script type="text/javascript" src="pikaday.js"></script>
<script type="text/javascript" src="jquery.ptTimeSelect.js"></script>
<script type="text/javascript" src="moment.js"></script>
<script>
    // initialize input widgets
    // ptTimeSelect doesn't trigger change event by default
    $('#alternateUiWidgetsExample .time').ptTimeSelect({
        'onClose': function($self) {
            $self.trigger('change');
        }
    });

    $('#alternateUiWidgetsExample .date').pikaday();

    var TIMEFORMAT = 'h:mm a';
    var alternateUiWidgetsExampleEl = document.getElementById('alternateUiWidgetsExample');
    var alternateWidgetsDatepair = new Datepair(alternateUiWidgetsExampleEl, {
        parseTime: function(input){
            // use moment.js to parse time
            var m = moment(input.value, TIMEFORMAT);
            return m.toDate();
        },
        updateTime: function(input, dateObj){
            var m = moment(dateObj);
            input.value = m.format(TIMEFORMAT);
        },
        parseDate: function(input){
            var picker = $(input).data('pikaday');
            return picker.getDate();
        },
        updateDate: function(input, dateObj){
            var picker = $(input).data('pikaday');
            return picker.setDate(dateObj);
        }
    });
</script>
            

Events Example

Datepair fires several events to indicate the status of the inputs.

to

// HTML not shown for brevity

// initialize input widgets first
$('#eventsExample .time').timepicker({
    'showDuration': true,
    'timeFormat': 'g:ia'
});

$('#eventsExample .date').datepicker({
    'format': 'm/d/yyyy',
    'autoclose': true
});

var eventsExampleEl = document.getElementById('eventsExample');
var eventsExampleDatepair = new Datepair(eventsExampleEl);

// some sample handlers
$('#eventsExample').on('rangeSelected', function(){
    $('#eventsExampleStatus').text('Valid range selected');
}).on('rangeIncomplete', function(){
    $('#eventsExampleStatus').text('Incomplete range');
}).on('rangeError', function(){
    $('#eventsExampleStatus').text('Invalid range');
});
            

Anchor Example

Datepair defaults to move the end time/date based on changes to the start time/date. This can be changed to the end inputs, or disabled completely.

Anchor:

to

var anchorExampleEl = document.getElementById('anchorExample');
var anchorDatepair = new Datepair(anchorExampleEl, {
    anchor: $('#anchorSelect').val()
});

$('#anchorSelect').on('change', function(){
    anchorDatepair.option('anchor', $('#anchorSelect').val());
});
            

Need Help?

Check the documenation or submit an issue on GitHub.