Custom editor field type plugin

Custom editor field type plugin

mguinnessmguinness Posts: 85Questions: 12Answers: 1

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

  • allanallan Posts: 63,691Questions: 1Answers: 10,500 Site admin

    That's excellent - thanks for sharing this with us!

    Allan

Sign In or Register to comment.