How should I sort null time values with Moment?

How should I sort null time values with Moment?

iamjonmilleriamjonmiller Posts: 8Questions: 3Answers: 0

I've been using the "Ultimate date/time sorting plugin" for awhile, and it really has made my life easier. All I had to do was make sure my Python backend was spitting out date/time values that match the format Moment is expecting and it will sort the columns correctly.

Recently I expanded some backend functions to include rows with null values for datetimes. In Python I sort these in Pandas by replacing the null value with a default datetime value. This allows these values to be compared correctly, but now I have a bunch of fake dates showing up in the datatable. I would prefer to replace that value on render with a something like "No Date" while preserving the Moment sorting functionality.

Is there any way I can tell Moment that if you see a certain string you should treat it as this value? Can I tell Moment to render a certain value as a string of my choice? Is there a certain value that I could set all of these null values to in Python, so that Moment knows that they really are empty?

I can provide some code samples, but I'm not sure how useful they would be considering that this really is a conceptual question.

Answers

  • iamjonmilleriamjonmiller Posts: 8Questions: 3Answers: 0
    edited October 2018

    I was thinking about adding something like this to the plugin source code:

    if (d === 'No Data') {
                    d = 'Dec 31, 1985, 12:00 AM';
                    return d;
     }
    

    But I'm clearly missing something because that breaks the table.

  • iamjonmilleriamjonmiller Posts: 8Questions: 3Answers: 0

    I solved this by modifying the plugin source:

    (function (factory) {
        if (typeof define === "function" && define.amd) {
            define(["jquery", "moment", "datatables.net"], factory);
        } else {
            factory(jQuery, moment);
        }
    }(function ($, moment) {
    
        $.fn.dataTable.moment = function (format, locale) {
            var types = $.fn.dataTable.ext.type;
    
            // Add type detection
            types.detect.unshift(function (d) {
                if (d) {
                    // Strip HTML tags and newline characters if possible
                    if (d.replace) {
                        d = d.replace(/(<.*?>)|(\r?\n|\r)/g, '');
                    }
    
                    // Strip out surrounding white space
                    d = $.trim(d);
                }
                if (d === 'No Data') {
                    return 'moment-' + format;
                }
    
                // Null and empty values are acceptable
                if (d === '' || d === null) {
                    return 'moment-' + format;
                }
    
                return moment(d, format, locale, true).isValid() ?
                    'moment-' + format :
                    null;
            });
    
            // Add sorting method - use an integer for the sorting
            types.order['moment-' + format + '-pre'] = function (d) {
                if (d) {
                    // Strip HTML tags and newline characters if possible
                    if (d.replace) {
                        d = d.replace(/(<.*?>)|(\r?\n|\r)/g, '');
                    }
                     if (d === 'No Data') {
                        d = 'Dec 31, 1985, 12:00 AM';
                    }
                    // Strip out surrounding white space
                    d = $.trim(d);
                }
    
                return !moment(d, format, locale, true).isValid() ?
                    Infinity :
                    parseInt(moment(d, format, locale, true).format('x'), 10);
            };
        };
    
    }));
    

    I was previously modifying the wrong part.

This discussion has been closed.