Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery UI Datepicker - Date range - Highlight days in between

I'm looking for a way of highlighting the days in between the date range of 2 inputs on mouse over.

This example is nearly doing what I want to achieve: http://hackingon.net/files/jquery_datepicker/range.htm

Only difference is that the highlighting of the selected range should happen on two separate datepickers and on mouse over.

Any suggestions?


Update:

Ok, a bit more details:

After selecting a date from the first datepicker, the second datepicker should highlight the previous selected date. If you then mouse over a day past the previous selected day, all days in between should highlight by adding a class.


Update: This is how far I got:

    $("#input-service_date_leave, #input-service_date_return").datepicker({
        rangeSelect: true,
        beforeShow: customRange,
        onSelect: customRange,
    });

    function customRange(input) {
        if (input.id == "input-service_date_leave") {

            $("#ui-datepicker-div td").die();

            if (selectedDate != null) { 
                $('#input-service_date_return').datepicker('option', 'minDate', selectedDate).datepicker('refresh');
            }
        }
        if (input.id == "input-service_date_return") {

            $("#ui-datepicker-div td").live({
                mouseenter: function() {
                    $(this).prevAll("td:not(.ui-datepicker-unselectable)").addClass("highlight");
                },
                mouseleave: function() {
                    $("#ui-datepicker-div td").removeClass("highlight");
                }
            });

            var selectedDate = $("#input-service_date_leave").datepicker("getDate");                
            if (selectedDate != null) { 
                $('#input-service_date_return').datepicker('option', 'minDate', selectedDate).datepicker('refresh');
            }
        }
    }

http://jsfiddle.net/mayko/WbWg3/1/

Only problem, the live event just highlights the td's of the current hovered row, but not the td's of the rows before.

Any ideas?

like image 321
Mayko Avatar asked Oct 20 '11 05:10

Mayko


People also ask

How do I highlight specific dates in jquery ui Datepicker?

datepicker({ beforeShowDay: function( date ) { var highlight = eventDates[date]; if( highlight ) { return [true, "event", 'Tooltip text']; } else { return [true, '', '']; } } }); The complete JavaScript code to highlight specific dates.

What is date range picker?

Originally built for reporting at Improvely, the Date Range Picker can be attached to any webpage element to pop up two calendars for selecting dates, times, or from predefined ranges like "Last 30 Days".


3 Answers

I added a bit to your script. Worked like a charm on JSFiddle. Take a look and let me know.

    $("#input-service_date_leave, #input-service_date_return").datepicker({
        rangeSelect: true,
        beforeShow: customRange,
        onSelect: customRange,
    });

    function customRange(input) {
        if (input.id == "input-service_date_leave") {

            $("#ui-datepicker-div td").die();

            if (selectedDate != null) {
                $('#input-service_date_return').datepicker('option', 'minDate', selectedDate).datepicker('refresh');
            }
        }
        if (input.id == "input-service_date_return") {

            $("#ui-datepicker-div td").live({
                mouseenter: function() {
                    $(this).parent().addClass("finalRow");
                    $(".finalRow").prevAll().find("td:not(.ui-datepicker-unselectable)").addClass("highlight");
                    $(this).prevAll("td:not(.ui-datepicker-unselectable)").addClass("highlight");
               },
                mouseleave: function() {
                    $(this).parent().removeClass("finalRow");
                    $("#ui-datepicker-div td").removeClass("highlight");
                }
            });

            var selectedDate = $("#input-service_date_leave").datepicker("getDate");                
            if (selectedDate != null) {
                $('#input-service_date_return').datepicker('option', 'minDate', selectedDate).datepicker('refresh');
            }
        }
    }
like image 177
CodeMonkeyG Avatar answered Nov 02 '22 22:11

CodeMonkeyG


edit: This script does not work on jquery 3. however it does work on version 1 and 2

this JSFiddle is an example of doing it with 2 date tables ( multiple months )

$("#input-service_date_leave, #input-service_date_return").datepicker({
    rangeSelect: true,
    beforeShow: customRange,
    onSelect: customRange,
    numberOfMonths: [1, 2],
});

function customRange(input) {
    if (input.id == "input-service_date_leave") {

        $("#ui-datepicker-div td").die();

        if (selectedDate != null) {
            $('#input-service_date_return').datepicker('option', 'minDate', selectedDate).datepicker('refresh');
        }
    }
    if (input.id == "input-service_date_return") {

        $("#ui-datepicker-div td").live({
            mouseenter: function() {
                $(this).parent().addClass("finalRow");
                $(".finalRow").parents('.ui-datepicker-group-last').parent().find('.ui-datepicker-group-first').find('tr').last().addClass("finalRowRangeOtherTable");
                $(".finalRowRangeOtherTable").find("td:not(.ui-datepicker-unselectable)").addClass("highlight");
                $(".finalRowRangeOtherTable").prevAll().find("td:not(.ui-datepicker-unselectable)").addClass("highlight");

                $(".finalRow").prevAll().find("td:not(.ui-datepicker-unselectable)").addClass("highlight");
                $(this).prevAll("td:not(.ui-datepicker-unselectable)").addClass("highlight");
           },
            mouseleave: function() {
                $(this).parent().removeClass("finalRow");
                $("#ui-datepicker-div td").removeClass("highlight");

                  $(".finalRowRange").removeClass("finalRowRange").find('.highlight').removeClass("highlight");
            $(".finalRowRangeOtherTable").removeClass("finalRowRangeOtherTable").find('.highlight').removeClass("highlight");

            }
        });

        var selectedDate = $("#input-service_date_leave").datepicker("getDate");                
        if (selectedDate != null) {
            $('#input-service_date_return').datepicker('option', 'minDate', selectedDate).datepicker('refresh');
        }
    }
}
like image 39
Aryeh Armon Avatar answered Nov 02 '22 23:11

Aryeh Armon


Made an example of date range hover for an inline datepicker here: http://codepen.io/denissamoilov/pen/RGKyPb?editors=0010

$(function(){
    var datepicker = {
        container: $("#datepicker"),
        dateFormat: 'mm/dd/yy',
        dates: [null, null],
        status: null,
        inputs: {
            checkin: $('#checkin'),
            checkout: $('#checkout'),
            dates: $('#dates')
        }
    };

    datepicker.container.datepicker({
        numberOfMonths: 2,
        dateFormat: datepicker.dateFormat,
        minDate: 0,
        maxDate: null,

        beforeShowDay: function(date) {
            var highlight = false,
            currentTime = date.getTime(),
            selectedTime = datepicker.dates;

            // Highlight date range
            if ((selectedTime[0] && selectedTime[0] == currentTime) || (selectedTime[1] && (currentTime >= selectedTime[0] && currentTime <= selectedTime[1]))) highlight = true;

            return [true, highlight ? 'ui-datepicker-select' : ""];
        },
        onSelect: function(dateText) {

            if (!datepicker.dates[0] || datepicker.dates[1] !== null) {
                // CHOOSE FIRST DATE

                // fill dates array with first chosen date
                datepicker.dates[0] = $.datepicker.parseDate(datepicker.dateFormat, dateText).getTime();
                datepicker.dates[1] = null;

                // clear all inputs
                datepicker.inputs.checkin.val('');
                datepicker.inputs.checkout.val('');
                datepicker.inputs.dates.val('');

                // set current datepicker state
                datepicker.status = 'checkin-selected';

                // create mouseover for table cell
                $('#datepicker').delegate('.ui-datepicker td', 'mouseover', function(){

                    // if it doesn't have year data (old month or unselectable date)
                    if ($(this).data('year') == undefined) return;

                    // datepicker state is not in date range select, depart date wasn't chosen, or return date already chosen then exit
                    if (datepicker.status != 'checkin-selected') return;

                    // get date from hovered cell
                    var hoverDate = $(this).data('year')+'-'+($(this).data('month')+1)+'-'+$('a',this).html();

                    // parse hovered date into milliseconds
                    hoverDate = $.datepicker.parseDate('yy-mm-dd', hoverDate).getTime();

                    $('#datepicker td').each(function(){

                        // compare each table cell if it's date is in date range between selected date and hovered
                        if ($(this).data('year') == undefined) return;

                        var year = $(this).data('year'),
                            month = $(this).data('month'),
                            day = $('a', this).html();

                        var cellDate = $(this).data('year')+'-'+($(this).data('month')+1)+'-'+$('a',this).html();

                        // convert cell date into milliseconds for further comparison
                        cellDate = $.datepicker.parseDate('yy-mm-dd', cellDate).getTime();

                        if ( (cellDate >= datepicker.dates[0] && cellDate <= hoverDate) || (cellDate <= datepicker.dates[0] && cellDate >= hoverDate) ) {
                            $(this).addClass('ui-datepicker-hover');
                        } else {
                            $(this).removeClass('ui-datepicker-hover');
                        }

                    });
                });

            } else {
                // CHOOSE SECOND DATE

                // push second date into dates array
                datepicker.dates[1] = $.datepicker.parseDate(datepicker.dateFormat, dateText).getTime();

                // sort array dates
                datepicker.dates.sort();

                var checkInDate = $.datepicker.parseDate('@', datepicker.dates[0]);
                var checkOutDate = $.datepicker.parseDate('@', datepicker.dates[1]);

                datepicker.status = 'checkout-selected';

                //fill input fields

                datepicker.inputs.checkin.val($.datepicker.formatDate(datepicker.dateFormat, checkInDate));
                datepicker.inputs.checkout.val($.datepicker.formatDate(datepicker.dateFormat, checkOutDate)).change();

                datepicker.inputs.dates.val(datepicker.inputs.checkin.val() + ' - ' + datepicker.inputs.checkout.val());

            }
        }
    });
});
like image 45
samoilov Avatar answered Nov 02 '22 23:11

samoilov