Custom editor field type plugin
Custom editor field type plugin
I had a need for a datepicker in editor which would allow selecting an approximate or exact date. In some cases the day or even the month would not be known.
This is also mentioned in Editor form datepicker with month and year only, but the discussion is now closed.
To use you define the field as circadate
field type with optional settings yearFrom
and yearTo
.
{
label: "Test:",
name: "dob",
type: "circadate",
yearFrom: 1950
}
Below is a screenshot of how this will look in the editor. It probably could do with some decent styling.
Below is the code that you will need to include in your project if you need to use this plugin. It's not perfect and needs some refining, so if anyone has improvements please share them here.
// Circadate field type plug-in code
(function ($, DataTable) {
if (!DataTable.ext.editorFields) {
DataTable.ext.editorFields = {};
}
var Editor = DataTable.Editor;
var _fieldTypes = DataTable.ext.editorFields;
_fieldTypes.circadate = {
create: function (conf) {
var that = this;
conf._enabled = true;
// Create the elements to use for the input
conf._input = $(
'<div id="' + Editor.safeId(conf.id) + '">' +
'<select type="button" class="selectYear" style="display:inline-block; width:auto">' +
'<option value="" selected>Year</option>' +
'</select>' +
'<select type="button" class="selectMonth" style="display:inline-block; width:auto">' +
'<option value="" selected>Month</option>' +
'</select>' +
'<select type="button" class="selectDay" style="display:inline-block; width:auto">' +
'<option value="" selected>Day</option>' +
'</select>' +
'</div>');
var year = new Date().getFullYear();
var from = conf.yearFrom || year;
var to = conf.yearTo || year;
for (var i = from; i <= to; i++) {
$('.selectYear', conf._input).append('<option>' + i + '</option>');
}
for (var i = 1; i <= 12; i++) {
var dt = new Date();
dt.setMonth(i - 1);
$('.selectMonth', conf._input).append('<option value="' + i + '">' + dt.toLocaleString('en-US', { month: 'short' }) + '</option>');
}
for (var i = 1; i <= 31; i++) {
$('.selectDay', conf._input).append('<option>' + i + '</option>');
}
$('.selectYear', conf._input).change(function () {
if (this.value === '') {
$('.selectMonth', conf._input).val('').change().attr('disabled', true);
}
else {
$('.selectMonth', conf._input).attr('disabled', false);
}
});
$('.selectMonth', conf._input).change(function () {
if (this.value === '') {
$('.selectDay', conf._input).val('').change().attr('disabled', true);
}
else {
var select = $('.selectDay', conf._input).attr('disabled', false);
var days = new Date($('.selectYear', conf._input).val(), $('.selectMonth', conf._input).val(), 0).getDate();
for (var i = 29; i <= 31; i++) {
select.find('option:eq(' + i + ')').attr('disabled', i > days);
}
}
});
return conf._input;
},
get: function (conf) {
var date = '';
var year = $('.selectYear', conf._input).val();
if (year) {
date += year;
var month = $('.selectMonth', conf._input).val();
if (month) {
date += '-' + month.padStart(2, '0');
var day = $('.selectDay', conf._input).val();
if (day) {
date += '-' + day.padStart(2, '0');
}
}
}
return date;
},
set: function (conf, val) {
var year = '';
var month = '';
var day = '';
if (val.length >= 4) {
year = val.substr(0, 4);
if (val.length >= 7) {
month = Number(val.substr(5, 2));
if (val.length >= 10) {
day = Number(val.substr(8, 2));
}
}
}
$('.selectYear', conf._input).val(year).change();
$('.selectMonth', conf._input).val(month).change();
$('.selectDay', conf._input).val(day);
},
enable: function (conf) {
conf._enabled = true;
$(conf._input).removeClass('disabled');
},
disable: function (conf) {
conf._enabled = false;
$(conf._input).addClass('disabled');
}
};
})(jQuery, jQuery.fn.dataTable);
Replies
That's excellent - thanks for sharing this with us!
Allan