Jeff Holoman's Blog

Adding Time to jQuery Datepicker

Posted by jholoman on May 15, 2009

A number of folks have blogged about using the jQuery datepicker in APEX. One of the redeeming qualities of the APEX datepicker widget is it’s support for a time component, which the jQuery datepicker lacks. I’m sure most of the time the ability to pick just the date is enough.  There are however times when you need finer granularity.   There are some seperate timepicker plugins, but having the date/time tied to one element is more natural in relation to the standard APEX datepicker. I’m posting to share one solution, but mostly to get other ideas on the best way to handle this occasion. I like the functionality and ease of implementation of the jQuery datepicker, but I’m not crazy about the work-around shown here to handle the time.

Check out this small demo in action here if you don’t want to read the whole post.

The jQuery docs show that you can use ‘…’ – literal text in your format string.

This allows the opportunity to append a time component to the standard format mask.  The solution presented here requires the user to manually edit the time component, so in order to accommodate this, a database function is created to validate the date. This could be done of course just using JavaScript but I think using the database to do the validation is easier.

create or replace function is_date(p_date in varchar2, p_format_mask_in in varchar2)
return boolean
as
  l_date date;
  l_format_mask varchar2(50);
begin
  l_format_mask := 'fx'||p_format_mask_in;
  l_date :=  to_date(p_date, l_format_mask);
   return true;
exception when others then
  return false;
end;

An on-demand application process, VALIDATE_DATE  is created to call the validation function, along with a corresponding javascript function to call it. I kept the is_date function a separate db function instead of rolling the functionality into the app process in case I had need for it elsewhere.

declare
 l_return number(1);
 l_date varchar2(50);
begin
l_date := wwv_flow.g_x01;
 if (is_date(l_date, v('PICK_DATE_FORMAT_MASK')))
 then
  l_return := 1;
 else
  l_return := 0;
 end if;
htp.p(l_return);
end;

validateDate

function validateDate (pDate, pOraFormatMask) {
 var get = new htmldb_Get(null,$v('pFlowId'), 'APPLICATION_PROCESS=VALIDATE_DATE', 0);
 var lDate = $(pDate).val();
 get.addParam('x01', lDate);
 var gReturn = get.get();
 get = null;
 if (gReturn==0)
 {   alert('Invalid Date Format Entered.\n Dates should be in '+ pOraFormatMask +' format.'); }
}

We’ll need two application items and corresponding computations to hold the different format masks, PICK_DATE_FORMAT_MASK and JS_DATE_FORMAT_MASK.

The format mask I want to use for Oracle  is ‘YYYY-MM-DD HH24:MI’, the jQuery datepicker mask that matches that is ‘yy-mm-dd’, but no time component.

I then create a hidden item on page zero, P0_JS_SYSDATE, with a source value of:

to_char(sysdate, ‘&PICK_DATE_FORMAT_MASK.’);

This will allow me to grab the time component easily for the datepicker.

All that’s left now is to call the the function that creates the datepicker:

function dpWithTime(pOraFormatMask, pDpFormatMask, pSysdate) {
   var timeFormat = " " + pSysdate.split(" ")[1];
  $('fieldset[class=datepicker]').find('img').css('display','none');
    $('fieldset[class=datepicker]').find('input[type=text]').datepicker({
        dateFormat: pDpFormatMask + timeFormat,
        showOn: "button",
        buttonImage: "/i/asfdcldr.gif",
        buttonImageOnly: true
        }).change(function(event) {validateDate(this, pOraFormatMask)});
}

In the html header for the page, or the page template:

<script type="text/javascript">
$(document).ready(function(){
var oraFormatMask = "&PICK_DATE_FORMAT_MASK.";
var jsFormatMask = "&JS_DATE_FORMAT_MASK.";
var l_sysdate =  $('#P0_JS_SYSDATE').val();
dpWithTime(oraFormatMask, jsFormatMask, l_sysdate);
});
</script>

Again the example is here.

Let me know if you have any other ideas, like I said at the start, I’m not thrilled with this approach, but if the rest of your app is already using the jQuery datepicker, and you need one with a time component maybe this will work. Thanks to Tyler Muth for his earlier blog/sample app using jQuery datepicker and for the bit about using the fieldset selector which he blogged about here.

Advertisements

3 Responses to “Adding Time to jQuery Datepicker”

  1. carsten said

    Hello Jeff,

    do you know the datetimepicker-plugin? I use this in my apex-application. Its great.

    http://plugins.jquery.com/project/DateTimepicker

    • jholoman said

      Carsten,

      I like this plugin, exactly what I was looking for. I missed it when I was searching before. I’ll modify the css and incorporate it on the example page.
      Thanks for the tip.

  2. Guido Zeleen said

    Hello Jeff,

    You could also change function dpWithTime as show below.


    function dpWithTime(pOraFormatMask, pDpFormatMask) {
    $('fieldset[class=datepicker]').find('img').css('display','none');
    $('fieldset[class=datepicker]').find('input[type=text]').datepicker({
    dateFormat: pDpFormatMask,
    showOn: "button",
    buttonImage: "/i/asfdcldr.gif",
    buttonImageOnly: true,
    beforeShow: function() {
    var time = $(this).val().split(' ')[1];
    var date = new Date();
    var hours= date.getHours();
    hours = new Array(3 - hours.toString(10).length).join('0') + hours;
    var minutes = date.getMinutes();
    minutes = new Array(3 - minutes.toString(10).length).join('0') + minutes;
    return {dateFormat: pDpFormatMask + ' ' + (time ? time : hours + ':' + minutes)}
    }
    }).change(function(event) {validateDate(this, pOraFormatMask)});
    }

    Kind regards,
    Guido

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Google+ photo

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

Connecting to %s

 
%d bloggers like this: