Search code examples
javascriptjqueryjqgridmomentjsfree-jqgrid

How to use external libraries in a custom formatter?


I have some data coming as a timestamp so I need to format it before it goes to the end user. I didn't found any way to achieve this using a predefined formatter from jQgrid.

Having said that I am trying to use a mix of "native" Javascript and MomentJS to format the data before display it.

The first thing I did was load the library momentjs before load jqgrid:

<script src="js/jquery-3.2.1.min.js" type="text/javascript"></script>
<script src="js/jquery-migrate-3.0.1.min.js" type="text/javascript"></script>
<script src="js/moment.min.2.20.1.js" type="text/javascript"></script>
<script src="js/free-jqgrid/jquery.jqgrid.min.js" type="text/javascript"></script>

Next I have created a custom formatter to be used in that column:

$.extend($.fn.fmatter, {
    customTimestampToDate: function (cellvalue, options, rowdata) {
        var parsed_timestamp = parseInt(rowdata.timestamp),
            tmp = new Date(parsed_timestamp * 1000).toISOString();

        console.log(typeof cellvalue); // logs string
        console.log(typeof rowdata.timestamp); // logs string
        console.log(typeof parsed_timestamp); // logs "number"
        console.log(tmp); // logs 2018-01-15T14:19:28.000Z

        return moment(tmp);
    }
});

Last I have tried to use the custom formatter in the colModel:

colModel: [
    {name: "act", template: "actions", width: 115},
    {name: "username", search: true, stype: "text"},
    {name: "email", search: true, stype: "text"},
    {name: "first_name", search: true, stype: "text"},
    {name: "last_name", search: true, stype: "text"},
    {name: "company", search: true, stype: "text"},
    {name: "request_uri", search: true, stype: "text"},
    {name: "client_ip", search: true, stype: "text"},
    {
        name: "timestamp",
        search: true,
        stype: "text",
        formatter: "customTimestampToDate"
    }
],

For some reason I am getting the timestamp value instead of the formatted one and I am not sure why or how.

I have been playing with momentjs on this Fiddle and it works as expected. I have been playing also with momentjs inside jqgrid in this Fiddle and as I am showing here is not working.

The problem: the issue here is the value being displayed as a string|int at timestamp column after the grid render which means the value on the column is the timestamp. The expected value would be the formatted one by moment doesn't matter if it's properly formatted or not (that's another different issue).

My guess is that the library hasn't been loaded when the grid is constructed or something like that but I am not sure at all.

Any ideas?

Note: Maybe there is an easy way to achieve this using a predefined formatter but I couldn't find it, if you know it let me know


Solution

  • As the docs says:

    To print out the value of a Moment, use .format(), .toString() or .toISOString().

    Your code could be like the following:

    customTimestampToDate: function (cellvalue, options, rowdata) {
        var parsed_timestamp = parseInt(rowdata.timestamp),
            tmp = new Date(parsed_timestamp * 1000).toISOString();
    
        return moment(tmp).format();
    }
    

    You can pass a format token to format() or use toISOString() to the the output in ISO 8601 compliant string.

    Note that moment accepts also Unix timestamps in seconds, so you can use moment.unix(Number), in your case: return moment.unix(rowdata.timestamp).format();