More fun with the JQuery UI Date Picker

More fun with the JQuery UI Date Picker

I have written about the JQuery UI date picker before, be sure to check out that article if you haven’t seen it. Today we got a request from a client that need the ability to allow the user to clear the date. So I had to put on my thinking (googling) cap and come up with a solution

In this particular project we open the data picker whenever the data entry control gains focus, which works well, but doesn’t have the side effect of there is no way to reset a date to blank at that point.

It didn’t take long with google to find a solution, which was

$(document).ready(function () {
    $(".datepicker").datepicker({
            showOn: 'focus',
            showButtonPanel: true,
            closeText: 'Clear', // Text to show for "close" button
            onClose: function () {
                var event = arguments.callee.caller.caller.arguments[0];
                // If "Clear" gets clicked, then really clear it
                if ($(event.delegateTarget).hasClass('ui-datepicker-close')) {
                    $(this).val('');
                }
            }
    });
});

So what this is doing is showing the button panel, which normally has a Today and a Close button. And it is changing the Close button to Clear and running a custom JavaScript function when the button is pressed.

All well and good, but how do we translate that to WebDev?

Let’s review our code from the article mentioned above for one of the date controls

dpobj is dynamic object = new "Object"
dpobj = setDatePickerDefaults()
dpobj.altField = "#EDTDATEPICKER1"
edtDatePicker1Display = DateToString(edtDatePicker1,"MM/DD/YYYY") 
jQuery("#EDTDATEPICKER1DISPLAY")."datepicker"(dpobj)

We don’t need to worry about showOn focus, we are already handling that. The next two are real easy.

dpobj.showButtonPanel = True
dpobj.closeText = "Clear"

We just add them to our object properties. Remember this is going to be accessed from JavaScript so you everything is case sensitive!

Now for the hard part how the heck to we handle that custom JavaScript function. I am sure there is more than one way to handle it, and this might not even be the best way, but we my hacker level knowledge of JQuery and JavaScript this is what works for me.

First we write a browser function. I right click on Local Procedures in the Project Explorer, and choose New local browser procedure. And I name it ClearDate. Again remember this will be case sensitive

That brings me to a new browser procedure in WL code

However we need to write this in JavaScript, so we click on the WL in the title bar and change it to JavaScript

Now we have a blank JavaScript function

All of that code about event arguments and delegateTarget is some belt and suspender code to make sure that this only effects controls that are data picker controls that have the button bar, but I couldn’t get it to work correctly and don’t really see the need for it as we are fully control when the function is called anyway. So I simplified the function to the one line of code we need

function ClearDate()
 {
     $(this).val('');
 }

Now that we have the function, how to we execute it on the onClose event? It’s actually really simple, we assign the function by reference with the magic of &

dpobj.onClose = &ClearDate

So now our full initialization code for the control is

dpobj is dynamic object = new "Object"
dpobj            = setDatePickerDefaults()
dpobj.altField    = "#EDTDATEPICKER1"
dpobj.showButtonPanel = True
dpobj.closeText = "Clear"
dpobj.onClose = &ClearDate
edtDatePicker1Display = DateToString(edtDatePicker1,"MM/DD/YYYY") 
jQuery("#EDTDATEPICKER1DISPLAY")."datepicker"(dpobj)

And as you can see at runtime, we now have a Clear button on the Calendar

Pressing it clears the date entry control. Note: You may need to tweak additional code to handle the blank date, but this gives the user the ability to clear the date.

Nov 28th 2020 Update

We discovered that sometimes this caused the calendar control to never update the date when selected it. It seems the ClearDate function was running on any close of the calendar. So I had to go back to the drawing board and adjust our function slightly. It should now read

function ClearDate()
 {
     if ($(window.event.srcElement).hasClass('ui-datepicker-close')) {
         $(this).val('');
     };
 }

Now it will only fire when the Clear button is pressed

The next issue is the Today button looking like it is disabled

It actually isn’t disabled, the default styling for the DatePicker is for the primary (default) button to look different than the secondary buttons. While we are on the topic, many folks, myself included, would expect hitting the today button would complete the picker and fill in today’s date. However, the default behavoir for the Today button is just to jump back to the current data, so it doesn’t really look like it is doing something unless you move to a different month, then it will jump back to the current month.

So we have 3 solutions for the Today button.

Solution 1 – Hide the Today button

This is the easiest option. It just involves a little CSS, you could have add this to some custom CSS file you load for the entire site, or add it to your page template so it would be on every page of your site or as I am doing here just on the page that has uses the date picker.

In the Page Description add the below CSS code to the HTML Page Header on the advanced tab like so

<style type='text/css'> .ui-datepicker-current { display: none; } </style>

Now the Today button doesn’t show at all

Solution 2 – Adjust the styling of the Today Button

If you just want the Today button to look like the Clear button then we just need to adjust its CSS

We simply change the CSS code that we add to the page header to this

<style type='text/css'>.ui-datepicker-current {opacity: 1 !important;font-weight: bold !important; } </style>

Note we have to use the !important keyword to insure that this setting will override the default settings

Solution 3 – Change the behavior of the Today button

For this solution we want to adjust the style as well as the behavior so go ahead and apply Solution 2 first then we will also adjust the behavior

We need to add another JavaScript function to our page. See the above info on the ClearDate function if you need help with that

function SelectToday()
 {
     var o_gotoToday = $.datepicker._gotoToday;
     $.datepicker._gotoToday = function (id) {
         o_gotoToday.call(this, id);
         this._selectDate(id);
         $(id).blur();
     }
 }

What this is doing is overriding the _gotoToday function that is built into the DatePicker and after making the call, it also calls the selectDate function to actually select the data as well as the blur function so that field has been exited incase the user wants to click back into the field to pop the calendar back up.

Now all you need to do is all this function during the Load (onload) browser event

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s