Reputation: 439
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?
Upvotes: 9
Views: 17217
Reputation: 2175
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');
}
}
}
Upvotes: 4
Reputation: 91
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());
}
}
});
});
Upvotes: 3
Reputation: 185
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');
}
}
}
Upvotes: 9