Date Picker Like Google Analytics Using JQuery UI

December 31, 2013

I’d been looking for a way of using the jQuery UI datepicker the same way that the Google Analytics datepicker works. Unfortunately I hadn’t found any solutions that I really liked. After a little more searching I found a tantalising piece of code that is already part of the jQuery UI Date Picker.

The piece of code is actually and Option, in this instance beforeShowDay. As the name suggests this piece of code is executed before the day is drawn. What I’ve done is pass the date of the day being drawn into the function and compared the date with some values I recorded earlier.

Based on some simple logic an array is returned (see the jQuery UI API documentation for more details), this important part for us is the class being added to the day (red for one selected period, blue for the second and split if any of the dates intersect.).

Now is this is great I can draw different coloured selected regions based on some stored dates. Now to make the ranges changeable.

I went back to the dates I was already storing. I knew that using the onSelect option I could use the date returned to my advantage. I stored the selected date in the object I’m using to hold the date ranges. But how to define the start and end?

I created a couple of input fields (a start and end) and a variable to track which field was being populated. On select the “selected field” is highlighted and the corresponding element in the date object is filled. Once the selection of a date is complete the focus is advanced to the next field.

The next step was simple I added a checkbox whose state determined if we were populating the first date range or another and added a couple more input boxes.

The resulting code you can find below and you can download a working example of the date picker. I think it’s a good starting point and you may wish to expand it’s functionality.

var dateRanges={
		"StartDate": new Date( 2013,11,18 ),
		"EndDate": new Date(2013,11,25), 
		"CompStartDate": new Date(2013,11,10 ),
		"CompEndDate": new Date(2013,11,17)
	};
var selection=1;
var range=1;
var compare=0;
var textMonths=new Array( 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' );

jQuery(document).ready(function(){

	jQuery("#selectDates").datepicker({
					
		changeMonth: true,
		dateFormat: 'yy/mm/dd',
		numberOfMonths: 3,
		beforeShowDay: function (date){
						
			if (date >= dateRanges.StartDate && date <= dateRanges.EndDate ) 
			{
								
				if (date >= dateRanges.CompStartDate && date <= dateRanges.CompEndDate && compare==1 )
				{
								
					return [true, 'split', ''];
								   
				}
								
				return [true, 'red', ''];
								
			}
							
			if (date >= dateRanges.CompStartDate && date <= dateRanges.CompEndDate && compare==1 ) 
			{
							
				if (date >= dateRanges.StartDate && date <= dateRanges.EndDate )
				{
								
					return [true, 'split', ''];
								   
				}                
								
				return [true, 'blue', ''];
								
			}       
							
			return [true, '', ''];
							
		},
		onSelect: function( selectedDate ){

			parts=selectedDate.split('/');

			if ( selection==1 )
			{

				if ( range==1 )
				{

					dateRanges.StartDate = new Date( parts[0], (parts[1]-1), parts[2] );

					jQuery('#fldRangeStart').val( dateRanges.StartDate.getDate()+' '+textMonths[dateRanges.StartDate.getMonth()]+' '+parts[0] );

				}
				else
				{

					dateRanges.CompStartDate = new Date( parts[0], (parts[1]-1), parts[2] );

					jQuery('#fldCompStart').val( dateRanges.CompStartDate.getDate()+' '+textMonths[dateRanges.CompStartDate.getMonth()]+' '+parts[0] );                    

				}

			}

			if ( selection==2 )
			{
						
				if ( range==1 )
				{
				
					dateRanges.EndDate = new Date( parts[0], (parts[1]-1), parts[2] );

					jQuery('#fldRangeEnd').val( dateRanges.EndDate.getDate()+' '+textMonths[dateRanges.EndDate.getMonth()]+' '+parts[0] );

				}
				else
				{

					dateRanges.CompEndDate = new Date( parts[0], (parts[1]-1), parts[2] );

					jQuery('#fldCompEnd').val( dateRanges.CompEndDate.getDate()+' '+textMonths[dateRanges.CompEndDate.getMonth()]+' '+parts[0] );

				}

			}

			selection=selection==1 ? 2 : 1;

			if ( selection==2 )
			{

				if ( range==1 )
				{

					jQuery('#fldRangeEnd').addClass('focusBorder');  
					jQuery('#fldRangeStart').removeClass('focusBorder');

				}
				else
				{

					jQuery('#fldCompEnd').addClass('focusBorder');
					jQuery('#fldCompStart').removeClass('focusBorder');

				}

			}
			else
			{

				if (range==1 )
				{

					jQuery('#fldRangeStart').addClass('focusBorder');
					jQuery('#fldRangeEnd').removeClass('focusBorder');

				}
				else
				{

					jQuery('#fldCompStart').addClass('focusBorder');
					jQuery('#fldCompEnd').removeClass('focusBorder');

				}
			
			}
			
		}

	});

	jQuery('#fldRangeStart').click(function(e){

		e.preventDefault();
		selection=1;
		range=1;
		jQuery('#fldRangeStart').addClass('focusBorder');  
		jQuery('#fldRangeEnd,#fldCompStart,#fldCompEnd').removeClass('focusBorder');

	});

	jQuery('#fldRangeEnd').click(function(e){

		e.preventDefault();
		selection=2;
		range=1;
		jQuery('#fldRangeEnd').addClass('focusBorder');  
		jQuery('#fldRangeStart,#fldCompStart,#fldCompEnd').removeClass('focusBorder');

	});    

	jQuery('#fldCompStart').click(function(e){

		e.preventDefault();
		selection=1;
		range=2;
		jQuery('#fldCompStart').addClass('focusBorder');  
		jQuery('#fldCompEnd,#fldRangeStart,#fldRangeEnd').removeClass('focusBorder');

	});

	jQuery('#fldCompEnd').click(function(e){

		e.preventDefault();
		selection=2;
		range=2;
		jQuery('#fldCompEnd').addClass('focusBorder');  
		jQuery('#fldCompStart,#fldRangeStart,#fldRangeEnd').removeClass('focusBorder');

	});    

	jQuery('#fldRangeStart').addClass('focusBorder');			
				
	jQuery('#fldCompare').click(function(){
				
		compare=compare==1 ? 0 : 1;
				
		if ( compare==1 )
		{

			jQuery('.compfields').show();
			jQuery('#selectDates').datepicker('refresh');
			
		}
		else
		{
		
			jQuery('.compfields').hide();
			jQuery('#selectDates').datepicker('refresh');
			
		}
				
	});

	jQuery('#fldRangeStart').val( dateRanges.StartDate.getDate()+" "+textMonths[dateRanges.StartDate.getMonth()]+" "+dateRanges.StartDate.getFullYear() );
	jQuery('#fldRangeEnd').val( dateRanges.EndDate.getDate()+" "+textMonths[dateRanges.EndDate.getMonth()]+" "+dateRanges.EndDate.getFullYear() );
	jQuery('#fldCompStart').val( dateRanges.CompStartDate.getDate()+" "+textMonths[dateRanges.CompStartDate.getMonth()]+" "+dateRanges.CompStartDate.getFullYear() );
	jQuery('#fldCompEnd').val( dateRanges.CompEndDate.getDate()+" "+textMonths[dateRanges.CompEndDate.getMonth()]+" "+dateRanges.CompEndDate.getFullYear() );				
	
	jQuery('.compfields').hide();
	
});
.red a
{

	background: #ff0000 none 0 0 no-repeat !important;

}

.blue a
{

	background: #0000ff none 0 0 no-repeat !important;
	color: #fff !important;

}

.split a
{

	background: #ff00ff none 0 0 no-repeat !important;

}
		
.datedsps
{

	width: 75px;
	font-size: 11px;

}

.focusBorder
{

	border: 2px solid #ff0000;

}
-

Compare Previous Period

-

Filed under: Programming — Tags: , , , , , , — admin @ 2:50 pm

3 Comments »

  1. Thanks for the plugin, I have to implement Custom option to select the dates. Please help me how to implement it

    Comment by shankar — July 29, 2015 @ 11:48 am

  2. What options are you trying to add?

    Comment by admin — July 29, 2015 @ 12:02 pm

  3. I am trying to add a select like in below URL

    http://www.jqueryscript.net/demo/Google-Style-Historical-Date-Range-Picker-Plugin-with-jQuery/

    Comment by shankar — July 31, 2015 @ 7:39 am

RSS feed for comments on this post. TrackBack URL

Leave a comment

About me

Jonathan Spicer

My CV

My curriculum vitae and a wealth of other facts about me.

Warhammer Quest tools

Flickering flame effect Flickering flame effect Flickering flame effect

Powered by WordPress