Handling Null Dates with Date Selectors

When working with dates on IBM i you will often need to deal with null date values of 0001-01-01.  Depending on the display format you’ve chosen, in a Valence UI designed with Ext JS a null date field will be rendered like this:

When the user clicks on the date selector trigger here, a calendar pops up based on the year and month specified in the field.  For a null date, the resulting date selector will look something like this:

The positioning of the calendar to January of the year 0001 is fairly inconvenient, as user are much more likely to want to pick a value closer to today’s date.  Of course, they could click on the “Today” button to set the field to today’s date, but doing so immediately sets the date and dismisses the calendar, so if they actually wanted a different date they would have to call up the calendar again and go on from there.  That’s also inconvenient. A better solution for null date values is to have the calendar automatically position itself to the current month, while still showing a null date in the field above so the user knows the date hasn’t yet been set.  To accomplish this let’s start by taking a look at the basic code for the date field above:

Ext.create('Ext.form.Panel', {
   renderTo: Ext.getBody(),
   width: 300,
   bodyPadding: 10,
   title: 'Null Date Example',
   items: [{
       xtype: 'datefield',
       anchor: '100%',
       fieldLabel: 'My Date',
       name: 'to_date',
       format: 'Y-m-d',
       value: '0001-01-01'
   }]
});

This code just displays a panel with a datefield inside of it and sets the initial value to a null date of 0001-01-01.  Based on the datefield API documentation, we know that when the user clicks the calendar trigger it fires an “expand” event on the datefield.  Thus, we can listen for that event and reset our calendar when the current value of the field is a null date:

Ext.create('Ext.form.Panel', {
   renderTo: Ext.getBody(),
   width: 300,
   bodyPadding: 10,
   title: 'Null Date Example',
   items: [{
       xtype: 'datefield',
       anchor: '100%',
       fieldLabel: 'My Date',
       name: 'to_date',
       format: 'Y-m-d',
       value: '0001-01-01',
       listeners: {
           expand: {
               delay: 50,
               fn: function(field) {
                   var d = Ext.util.Format.date(field.getValue(),'Y-m-d');
                   if (d === '0001-01-01') {
                       field.picker.setValue(new Date());
                   }
               }
           }
       }
   }]
});

In the listener code above (blue text), you’ll notice that there is a 50ms delay.  This gives the calendar time to open up before the function attempts to change its date.  The subsequent “if” statement checks to see if the current field value is null.  If it is null it uses the field.picker.setValue(new Date()); statement to set the position of the calendar to today’s date without changing the value in the field. With this change in place, when the calendar is opened with a null date it will position to today’s date instead of January 0001, while still showing the null date in the field so they know a value has not yet been specified:

This is just one example of how you can make date fields a little more convenient for your users to work with.