Random thoughts & observations

From the mundane to the profound and everything in between here’s what’s rocking our world

Hiding the jQuery UI datepicker on form field exit

Posted: March 21, 2015
Written by: Saints At Play
Category: jQuery UI

If you've been implementing the jQuery UI datepicker component in your projects you may have encountered an issue with the datepicker not closing when exiting the parent field or clicking outside the widget.

You've followed the official documentation, initialised your datepicker with the appropriate options (if and where applicable) and assigned the necessary events for displaying/hiding the component against the input field it's related to. The only sticking point is when you come to test your datepicker.

It just won't close.

Tabbing away from the input field or clicking outside the opened datepicker has no effect and the documentation leaves you none the wiser as to what might be causing this or even how to remedy the situation.

Fixing this, however, is not as complicated or challenging as it may first appear.

Before we proceed

The tutorial presumes that you are using the following libraries/versions:

  • jQuery (v1.8.3)
  • jQueryUI (v1.11.1)

It's also presumed that you follow best practice development and place your JavaScript in external files that are organised in a manageable directory structure. For example:

 css
   - custom
   - third-party
 images
 js
   - custom // Your own scripts
   - third-party // libraries/plugins
 index.html 

Implementing a functional datepicker

With the necessary JavaScript libraries and custom script(s) being called via <script> tags placed in the header or footer of your web page your HTML structure for the datepicker might look something like this:

// Place the following between the body tags of your HTML page
<div class="datepicker-wrapper">
  <input type="text" id="preferred-date" class="datepicker-date-selection">
  <div id="datepicker-for-preferred-date" class="datepicker"></div>
</div>

Now that our HTML structure for the date picker is set-up we can look at implementing the necessary functionality in our JavaScript.

In the external JS file that handles your website/app JavaScript you'll want to treat the initialisation of the datepicker as a method that can be called in the jQuery document ready call. Let's assume you are using object oriented programming to better manage your scripts along with the use of namespaces to help avoid collisions with different classes.

With this in mind the following code snippet demonstrates how we might handle the configuration and set-up of the datepicker component:

SAP.formHandler = {

 initialiseDatePickerWidget : function() {
  $('#datepicker-for-preferred-date').datepicker({ 
    showOn: 'both',
    direction: 'down',
    autoSize: true,
    minDate: 0, 
    maxDate: '1M',
    dateFormat: 'dd/mm/yy',
    onSelect: function(date) {
      $('.datepicker-date-selection').val(date);
      $(this).hide();
    }
  });
 }

}

With this widget initialisation script in place we can now look at handling the events for opening and closing our datepicker component:

handleOpeningDatePicker : function() 
{
  $('.datepicker-date-selection').on("select, focus", function(e)
  {	
	if($('#datepicker-for-preferred-date').hasClass('hasDatepicker'))
	{
	  $('.hasDatepicker').show();
	}
	else 
	{
	  SAP.formHandler.initialiseDatePickerWidget();
	}
  });
},


hideDatePicker : function()
{
  $('#datepicker-for-preferred-date').hide();
},


handleClosingDatePicker : function()
 {
  $('.datepicker-date-selection').on("blur", function(e)
  {	
	SAP.formHandler.hideDatePicker();
  });
}

The handleOpeningDatePicker() method performs a conditional check to determine whether or not the date picker widget has been previously opened through detecting whether the hasDatePicker class exists or not. This class is automatically attached to the date picker component when created by jQuery UI making it a hook/handy reference point for detection purposes.

If this class does exist then we call the show() method of the datepicker widget. If the class doesn't exist then we call the initialiseDatePickerWidget() method that we created earlier.

Closing the datepicker widget is handled on the form field blur event and simply calls the hideDatePicker() method from within our handleClosingDatePicker() method. Nothing terribly complicated or convoluted there - thankfully!

Our full script will now look like this:

SAP.formHandler = {

 initialiseDatePickerWidget : function() {
  $('#datepicker-for-preferred-date').datepicker({ 
    showOn: 'both',
    direction: 'down',
    autoSize: true,
    minDate: 0, 
    maxDate: '1M',
    dateFormat: 'dd/mm/yy',
    onSelect: function(date) {
      $('.datepicker-date-selection').val(date);
      $(this).hide();
    }
  });
 },


 handleOpeningDatePicker : function() 
 {
  $('.datepicker-date-selection').on("select, focus", function(e)
  {	
	if($('#datepicker-for-preferred-date').hasClass('hasDatepicker'))
	{
	  $('.hasDatepicker').show();
	}
	else 
	{
	  SAP.formHandler.initialiseDatePickerWidget();
	}
  });
 },


 hideDatePicker : function()
 {
   $('#datepicker-for-preferred-date').hide();
 },


 handleClosingDatePicker : function()
 {
   $('.datepicker-date-selection').on("blur", function(e)
   {	
	 SAP.formHandler.hideDatePicker();
   });
 }
}

Implementing these, for those not accustomed to object-oriented programming in JavaScript, is relatively trivial. After the final closing brace of the above script create a few carriage returns and enter the following snippet to call the methods on jQuery's DOM ready event:

$(document).ready(function(){
  SAP.formHandler.initialiseDatePickerWidget();
  SAP.formHandler.handleOpeningDatePicker();
  SAP.formHandler.handleClosingDatePicker();
});

One potential gotcha

If you use CSS absolute positioning for the DOM element that the date picker component is attached to you might find this prevents the component being able to close under some circumstances. If this should be the case use relative positioning within your CSS rule for this component instead.

Parting shot

Although we jumped through a few hoops with setting up the HTML for our page and creating the necessary methods in our JavaScript the overall process wasn't too complex or challenging.

As a result you now have a solution for initialising, opening and closing your jQuery UI datepicker!

« Return to Posts

Comments

There are no comments

Posting comments after three months has been disabled.