13th Jan 2020Problems with default datetime in editor
With this latest suggestion from Allan, I've solved the problems discussed here. Not all of these issues were evident in the original question. In the whole process I've learned several other things that I think might be useful to others. I'm posting an overview of what I've learned as it might be helpful to others.
I've learned useful things about processing date and time information, filtering data, and orthogonal data. Let me describe the situation:
The origin of this discussion was an attempt to write code that would allow me to filter a dueDate as to being overdue ( older than today ), today, tomorrow, or beyond ( later than tomorrow ), as required by my client's business case.
I began by computing this filtering data in PHP on the server, as I'm reasonably familiar with date manipulation in PHP. I was then returning this data as an object containing the displayDate and the filterDate ( as orthogonal data ). I'd been trying to use the jQuery DatePicker, as it is used elsewhere in the program. However, the jQuery DatePicker could not deal with the object I'd created to contain the orthogonal data, and I did not figure out a way to present jQuery with just what it needed.
I then followed Allan's suggestion to simply format the date on the server and do all of the other date manipulation work for this field on the client, so I deleted the code that computed the filter terms. I also realized in the process that I did not need to deliver the orthogonal data from the server to the client as most of the examples in the DataTables documentation do. Rather, I set up my definition of the dueDate field on the server to render the date in display form except when the type of data to be rendered was 'filter', in which case I returned the filterDate as overdue, today, tomorrow, or beyond, as used in the column filter routine. I believe that doing this made the filter code easier to read and understand than it would have been if I had tried to do that date computations within the filtering code itself.
To summarize several things I learned:
It can be very helpful to keep date processing on the server-side restricted to ISO-8601 format.
Orthogonal data can be created on the client as needed, when you are rendering a field that needs it. It does not need to be sent from the server. ( It is easy to unnecessarily generalize from examples you see. )
Beware of using features of jQuery, as the data as used in DataTables / Editor may not be directly consumable by jQuery. What you want to do may not be possible with the data in the form that DataTables / Editor uses.
Following are come code segments to illustrate how I've done this, as I think these might be helpful to others, especially if it's your first try at doing some of these types of things:
First is the code for computing definitions of the filter terms, overdue, today, tomorrow, and beyond ( I make no claim that these are the best possible ways to do this date manipulation, as this code is just my first solution. You can quite likely do better ):
// Here we compute definitions for filtering tasks by dueDate
// Note that we adjust to Eastern Time Zone, where this code will be used
var year, month, date;
var d = new Date();
year = d.getUTCFullYear();
month = d.getUTCMonth();
date = d.getUTCDate();
var today = new Date(year,month,date);
var todayMs = today.getTime() - 60 * 60 * 5 * 1000;
var tomorrow = new Date( 86400 * 1000 + today.getTime());
var tomorrowMs = tomorrow.getTime() - 60 * 60 * 5 * 1000;
var beyond = new Date( 86400 * 1000 + tomorrow.getTime());
var beyondMs = beyond.getTime() - 60 * 60 * 5 * 1000;
truth = true;
// End of definitions and computations for filtering tasks
Next is the definition of the dueDate column in the client Javascript:
{
"data": "duedate",
"className": "dFilter",
"render": function( data, type, row ) {
// If filtering, return overdue, today, tomorrow, beyond, as computed
if (type === 'filter') {
theDueDate = new Date(data);
filterDate = ''; // Initialize empty
if ( theDueDate.getTime() < todayMs ) {
filterDate = 'overdue';
}
if ( theDueDate.getTime() >= beyondMs ) {
filterDate = 'beyond';
}
if ( theDueDate.getTime() === todayMs ) {
filterDate = 'today';
}
if ( theDueDate.getTime() === tomorrowMs ) {
filterDate = 'tomorrow';
}
return filterDate;
} else {
// If not filtering, return the dueDate itself in displayDate form
return data;
}
}
},
Next is the column filter itself as it is applied to the dueDate field. ( Note that this filter is applied to the columns with the dFilter class ):
this.api().columns('.dFilter').every( function () {
var column = this;
var that = this;
var select = $('<select><option value="">All</option><option value="overdue">Overdue</option><option value="today">Today</option><option value="tomorrow">Tomorrow</option><option value"beyond">Beyond</option></select>')
.appendTo( $(column.header()) )
.on( 'change', function() {
that
.search ($(this).val() )
.draw();
} );
} );
I post this in the hope that it might help someone else who is grappling with some of these issues by pulling together several of these issues into one posting.
Many thanks to Allan and Colin for leading me to a working solution,
Tom