Friday, September 28, 2012

Dynamic Date Range in APEX Datepicker - no Plugin required

datepicker01
The build in jQuery UI Datepicker of Application Express is a very versatile component and it is very easy to configure the basic settings with the Page Item properties. One of the properties you can set, is the range of selectable dates by entering a Minimum and Maximum Date value. The “syntax” of these values is based on the jQuery UI Datepicker components date format capabilities, so this might be looking a bit awkward to us Oracle folks at first sight. Next to giving a static value or one of these Datepicker calculations you can reference an APEX Page Item to set the range values, which is a nice thing as we are able to calculate a range dynamically, based on some database value/calculations. The bummer is: the calculation only gets executed during the rendering phase of the page and changing the referencing Page Item’s value won’t change the Datepicker range.
What you really want (yes, you do), is to be able to reference Page Items to control the Minimum and Maximum Date dynamically “real-time”. Think of all the examples where you have to enter a Start Date and an End Date, where the End Date, obviously, has to be larger then the Start Date. In my case, I had different “events” to choose from and, once having chosen, pick a day within the events date range. You could just solve this by validating the users input and notifying him after he entered the date value. I prefer to restrict the user input to valid values.

The Basics: jQuery Datepicker in APEX

datepicker01
I created this little demo page, containing 3 standard APEX date items. Searching for “datepicker” in the page’s source code (using the Chrome Developer Tool), I found 3 corresponding jQuery calls, one for each item, to initialize the datepicker objects. Nice thing is, the Datepicker objects are named after the original APEX page items. As those objects are created during initial rendering of the page, we should be able to access them with jQuery by using the console. If we are able to access these Datepicker objects, we also should be able to alter the options, using the methods defined for the jQuery UI Datepicker object.

Let’s Get

OK, lets have a look at the objects using the Chrome Console: I want to get the value of the page item and see some of the Datepicker option settings.
Querying the page items value is pretty straight forward using jQuery selectors with the elements ID’s:
  • $("#P1_MAX_DATE").val()to get the value of the second date item
  • $("#P1_DATE").datepicker( "option", "minDate")to read the minDate option of the third date item
datepicker02datepicker03
As you see I already entered a min and max Date when defining the third date item, using “-7d” and “+7d” as values, So, now we know how to read the page item value and the Datepicker options.

Set it


Let’s try to alter some options, and obviously, I’m going to try to set the minDate and maxDate options with
$("#P1_DATE").datepicker( "option", "minDate", "04-09-2012")
and
$("#P1_DATE").datepicker( "option", "maxDate", "29-09-2012")

datepicker04
Well, it works! This is what the Datepicker looks like after setting the min- and maxDate.

Wrap it up


If now we combine getting the values of the Min./Max. Date page items and setting the the minDate/maxDate options of the “Actual Date”  item, put this into a Dynamic Action, lets say: “execute JavaScript on the Change events of the first two date fields”, we should have exactly the intended behavior.

Start the Dynamic Action Wizard by right-clicking on the P1_MIN_DATE item and choosing “Create Dynamic Action”:
datepicker05
datepicker06
datepicker07
datepicker08

Do the same for P1_MAX_DATE using the code:

$("#P1_DATE").datepicker( "option", "maxDate", $("#P1_MAX_DATE").val());

Just two statements! See for yourself and visit the demo page. Of course the variations of this approach are countless, but the basic two statements will remain: getting the value and setting the range options.

Have fun APEX-ing.

themes4apex