Trying to renderCell with images based on timestamp in epoch time

3196
7
Jump to solution
04-10-2014 11:32 AM
MichelleRogers1
New Contributor III
I am trying to use renderCell in dgrid to show whether a certain vehicle is transmitting or not.  We have a TimeStamp field, but the time coming in from the GPS unit is epoch time.  I have done a formatter and can get the time to come in correctly, but we don't really want the date and time to show on the grid.  We want an image of a green circle to show if the timestamp is the current time, and a red circle to show if the timestamp is not the current time(so that we know when a gps unit is possibly malfunctioning and so that others looking at the screen know that the position may not be accurate).  This is the code I have come up with so far for the renderCell:

function transmittingRenderCell(object, value, cell, options){  var greenLight = new Image();  greenLight.src = "images/greenLight.png";  var redLight = new Image();  redLight.src = "images/redLight.png";  var inputDate = new Date(value);  return dojo.date.locale.format(inputDate);  var currentDateTime = new Date();  //var day = currentDateTime.getDate();  //var month = currentDateTime.getMonth()+1;  //var year = currentDateTime.getFullYear();  //var hours = currentDateTime.getHours();  //var minutes = currentDateTime.getMinutes();  //var date = month + "/" + day + "/" + hours + ":" + minutes;  if(inputDate = currentDateTime){   return greenLight;  }  //else{   //return redLight;  //} }


It took me awhile to come up with the code to get the currentDateTime, so any help in figuring this out is appreciated.
0 Kudos
1 Solution

Accepted Solutions
JonathanUihlein
Esri Regular Contributor
Jon,

I tried the formatter with get, and the images are showing, but not correctly.  They all show red even though there should be some red and some green.  I think this has to do with the fact that the original TimeStamp is in epoch time and I am trying to compare it to the new Date().  Is there a way to format it, then compare the formatted TimeStamp?  Or, do I need to create a new column and compare the formatted column to new Date(), then use Column Hider to hide the formatted TimeStamp column so that all that shows is the image?  You are helping me with another issue, and the information for this issue is in the jsfiddle for that one.  It's the same website.

Again, any help is much appreciated.

You can do everything from within get() and formatter(). No need for another column just for math.

I have a perfect code sample that you should be able to manipulate for your use case.

In one of my data grid applications, I compare an epoch timestamp to the current time and print how long ago the timestamp was.

NOTE:
- I don't use get() because I only need the value of that particular cell on that particular row
- lastMod is the name of my column and it represents when the data in that row was 'last modified.'
- value represents the specific value of lastMod in this function

columns: [ {               label:"Last Seen",                field: "lastMod",               formatter: function(value){                 var timeStamp = new Date(value);                 var minutesAgo = Math.floor((new Date().getTime() - value) / 60000);                 if(minutesAgo > 0 && minutesAgo < 1){minutesAgo = 1};                 if(minutesAgo > 60){                   var hours = minutesAgo / 60;                     if( hours > 24){                     var days = hours / 24;                     return Math.floor(days) + " Day(s)";                     }                   return Math.floor(hours) + " Hour(s)";                 }                 return minutesAgo + " Minute(s)";               }             } ];


Psuedo Code:
 //1397236556000 var lastUpdated = 1397236556000;  //1397248094113 var rightNow = new Date().getTime();  // var minutesSinceLastUpdate = Math.floor((1397248094113 - 1397236556000) / 60000); // var minutesSinceLastUpdate = Math.floor((rightNow  - lastUpdated) / 60000); var minutesSinceLastUpdate = Math.floor((new Date().getTime() - lastUpdated ) / 60000);  //minutesSinceLastUpdate is equal to 192 Minutes 

View solution in original post

0 Kudos
7 Replies
JonathanUihlein
Esri Regular Contributor
Am I correct in assuming that the images are in their own column (a unique cell on each row in the table)?
0 Kudos
MichelleRogers1
New Contributor III
Am I correct in assuming that the images are in their own column (a unique cell on each row in the table)?


Actually, I am trying to replace the date and time information with an image in the Last Contact column.
0 Kudos
JonathanUihlein
Esri Regular Contributor
Ah I thought I said that. My mistake!

I've not used renderCell much.
I prefer using get() and formatter() together for rendering HTML within cells (images in particular).
It lets you check/pass values of other cells on that row as well.

According to the documentation: (https://github.com/SitePen/dgrid/wiki/Grid)
(Note: if formatter is specified, renderCell is ignored.)

^ This makes sense, because they really do the same thing.
Formatter is more friendly with raw HTML I believe, so you might want to use that.


The workflow is basically...

1) get() has access to the row in object form.
2) Whatever you return from the get() function is passed to formatter()
3) formatter() returns the actual text/image etc to be rendered in that cell.

Here is a working JSFiddle that checks the value of col3 using an if statement and either returns a green div, or a red image, or the default value of that cell.

http://jsfiddle.net/sxQ3m/1/


<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>dynamic dgrid columns</title>
    <link rel="stylesheet" href="https://community.esri.com//ajax.googleapis.com/ajax/libs/dojo/1.9.1/dojo/resources/dojo.css">
    <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.5/js/dojo/dijit/themes/tundra/tundra.css" />
    <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.5/js/dgrid/css/dgrid.css">
    <style type="text/css">

    body, html{
        margin:0;
        padding:0;
        height:100%;
        width:100%;
    }
    #grid{
        border:0px;
        width:100%;
        height:100%;
    }
        
  </style>
      <link rel="stylesheet" href="http://js.arcgis.com/3.9/js/esri/css/esri.css">
      <script src="http://js.arcgis.com/3.8/"></script>
    
    <script>
  
  var data = [{"id":0,"col1":"normal","col2":false,"col3":"new","col4":"But are not followed by two hexadecimal","col5":29.91,"col6":10,"col7":false},{"id":1,"col1":"important","col2":false,"col3":"new","col4":"Because a % sign always indicates","col5":9.33,"col6":-5,"col7":false},{"id":2,"col1":"important","col2":false,"col3":"read","col4":"Signs can be selectively","col5":19.34,"col6":0,"col7":true},{"id":3,"col1":"note","col2":false,"col3":"read","col4":"However the reserved characters","col5":15.63,"col6":0,"col7":true},{"id":4,"col1":"normal","col2":false,"col3":"replied","col4":"It is therefore necessary","col5":24.22,"col6":5.5,"col7":true},{"id":5,"col1":"important","col2":false,"col3":"replied","col4":"To problems of corruption by","col5":9.12,"col6":-3,"col7":true},{"id":6,"col1":"note","col2":false,"col3":"replied","col4":"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris","col5":12.15,"col6":-4,"col7":false},{"id":7,"col1":"normal","col2":false,"col3":"new","col4":"But are not followed by two hexadecimal","col5":29.91,"col6":10,"col7":false},{"id":8,"col1":"important","col2":false,"col3":"new","col4":"Because a % sign always indicates","col5":9.33,"col6":-5,"col7":false},{"id":9,"col1":"important","col2":false,"col3":"read","col4":"Signs can be selectively","col5":19.34,"col6":0,"col7":true},{"id":10,"col1":"note","col2":false,"col3":"read","col4":"However the reserved characters","col5":15.63,"col6":0,"col7":true},{"id":11,"col1":"normal","col2":false,"col3":"replied","col4":"It is therefore necessary","col5":24.22,"col6":5.5,"col7":true},{"id":12,"col1":"important","col2":false,"col3":"replied","col4":"To problems of corruption by","col5":9.12,"col6":-3,"col7":true},{"id":13,"col1":"note","col2":false,"col3":"replied","col4":"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris","col5":12.15,"col6":-4,"col7":false},{"id":14,"col1":"normal","col2":false,"col3":"new","col4":"But are not followed by two hexadecimal","col5":29.91,"col6":10,"col7":false},{"id":15,"col1":"important","col2":false,"col3":"new","col4":"Because a % sign always indicates","col5":9.33,"col6":-5,"col7":false},{"id":16,"col1":"important","col2":false,"col3":"read","col4":"Signs can be selectively","col5":19.34,"col6":0,"col7":true},{"id":17,"col1":"note","col2":false,"col3":"read","col4":"However the reserved characters","col5":15.63,"col6":0,"col7":true},{"id":18,"col1":"normal","col2":false,"col3":"replied","col4":"It is therefore necessary","col5":24.22,"col6":5.5,"col7":true},{"id":19,"col1":"important","col2":false,"col3":"replied","col4":"To problems of corruption by","col5":9.12,"col6":-3,"col7":true},{"id":20,"col1":"note","col2":false,"col3":"replied","col4":"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris","col5":12.15,"col6":-4,"col7":false},{"id":21,"col1":"normal","col2":false,"col3":"new","col4":"But are not followed by two hexadecimal","col5":29.91,"col6":10,"col7":false}];

  
  
        require([
            "dojo/_base/declare", 
            "dgrid/OnDemandGrid", 
            "dojo/ready",
            "dojo/store/Memory",
        ],
        function(declare, OnDemandGrid, ready, Memory){

            ready(function () {
                
                var dataStore;
                var CustomGrid = declare([ OnDemandGrid]);
        
        
                var grid = new CustomGrid({
            bufferRows: Infinity,
            cellNavigation: false,
            escapeHTMLInData: false,
            noDataMessage: "NO DATA",
            loadingMessage: "LOADING",
            selectionMode: "single",
                }, "grid");
                    
            
      var columnExample1 = [
      {
        "field": "col1",
        "label" : "col1"
      },
      {
        "field": "col2",
        "label" : "col2"
      },
      {
        // You can reuse field values to create compound columns
        "field": "col2",
        "label" : "SUPER COLUMN",
        "formatter" : function (value) {
          return "col1: " +value[0] + " ... col2: " + value[1];
        },
        "get" : function (obj) {
            // obj represnts the the whole row... you can access different cells by their field
            // E.G. obj.col1 or obj.col3
            return [obj.col1, obj.col2];
        }
      },
      {
        "field": "col3",
        "label" : "col3",
        "formatter" : function (value) {
          return value;
        },
        "get" : function (obj) {
            if(obj.col3 === "new"){
              return "<div style='width:15px; height:15px; background-color:green;'></div>";
            }else if(obj.col3 === "read"){
                       return "<img src='http://upload.wikimedia.org/wikipedia/commons/5/52/Small_red_circle.png' />";   
            }
            return obj.col3;
        }
      },
      {
        "field": "col4",
        "label" : "col4",
        "formatter" : function (value) {
          return value;
        },
        "get" : function (obj) {
            return obj.col4;
        }
      }

      ];
            
        // Set Columns
        grid.setColumns(columnExample1);
        
        // If you use a store...
        dataStore = new Memory ({"data": data});
        grid.set("store", dataStore);

        
        grid.startup();

            });
        });
    </script>
</head>
<body class="tundra"></body>
</html>


MichelleRogers1
New Contributor III
Jon,

I tried the formatter with get, and the images are showing, but not correctly.  They all show red even though there should be some red and some green.  I think this has to do with the fact that the original TimeStamp is in epoch time and I am trying to compare it to the new Date().  Is there a way to format it, then compare the formatted TimeStamp?  Or, do I need to create a new column and compare the formatted column to new Date(), then use Column Hider to hide the formatted TimeStamp column so that all that shows is the image?  You are helping me with another issue, and the information for this issue is in the jsfiddle for that one.  It's the same website.

Again, any help is much appreciated.
0 Kudos
JonathanUihlein
Esri Regular Contributor
Jon,

I tried the formatter with get, and the images are showing, but not correctly.  They all show red even though there should be some red and some green.  I think this has to do with the fact that the original TimeStamp is in epoch time and I am trying to compare it to the new Date().  Is there a way to format it, then compare the formatted TimeStamp?  Or, do I need to create a new column and compare the formatted column to new Date(), then use Column Hider to hide the formatted TimeStamp column so that all that shows is the image?  You are helping me with another issue, and the information for this issue is in the jsfiddle for that one.  It's the same website.

Again, any help is much appreciated.

You can do everything from within get() and formatter(). No need for another column just for math.

I have a perfect code sample that you should be able to manipulate for your use case.

In one of my data grid applications, I compare an epoch timestamp to the current time and print how long ago the timestamp was.

NOTE:
- I don't use get() because I only need the value of that particular cell on that particular row
- lastMod is the name of my column and it represents when the data in that row was 'last modified.'
- value represents the specific value of lastMod in this function

columns: [ {               label:"Last Seen",                field: "lastMod",               formatter: function(value){                 var timeStamp = new Date(value);                 var minutesAgo = Math.floor((new Date().getTime() - value) / 60000);                 if(minutesAgo > 0 && minutesAgo < 1){minutesAgo = 1};                 if(minutesAgo > 60){                   var hours = minutesAgo / 60;                     if( hours > 24){                     var days = hours / 24;                     return Math.floor(days) + " Day(s)";                     }                   return Math.floor(hours) + " Hour(s)";                 }                 return minutesAgo + " Minute(s)";               }             } ];


Psuedo Code:
 //1397236556000 var lastUpdated = 1397236556000;  //1397248094113 var rightNow = new Date().getTime();  // var minutesSinceLastUpdate = Math.floor((1397248094113 - 1397236556000) / 60000); // var minutesSinceLastUpdate = Math.floor((rightNow  - lastUpdated) / 60000); var minutesSinceLastUpdate = Math.floor((new Date().getTime() - lastUpdated ) / 60000);  //minutesSinceLastUpdate is equal to 192 Minutes 
0 Kudos
MichelleRogers1
New Contributor III
Jon,

I tried your solution, bringing in the information i believed would be helpful, but the grid is not populating at all.  Here is the code for all the columns for that grid.

columns: {              
 "id": {"label": "", renderCell: actionRenderCell},              
 "vehicleid": "Unit ID",              
 "velocity": { "label": "Speed (MPH)", "formatter": dojoNum.format },
 "timestamp":{"label":"Last Contact", "formatter":function(value){
  var lastMod = new Date(value);
  var minutesAgo=Math.floor((newDate().getTime()- lastMod)/60000);
  if(minutesAgo>15){return "<img src='images/redLight'/>";}
  else{return "img src='images/greenLight'/>";}
 }}
}


I want the red circle to show up if minutesAgo is greater than 15, otherwise the green circle should show.  I believe this is the correct code, but am not sure why it's not populating the grid.
0 Kudos
MichelleRogers1
New Contributor III
Jon,

I tried your solution, bringing in the information i believed would be helpful, but the grid is not populating at all.  Here is the code for all the columns for that grid.

columns: {              
 "id": {"label": "", renderCell: actionRenderCell},              
 "vehicleid": "Unit ID",              
 "velocity": { "label": "Speed (MPH)", "formatter": dojoNum.format },
 "timestamp":{"label":"Last Contact", "formatter":function(value){
  var lastMod = new Date(value);
  var minutesAgo=Math.floor((newDate().getTime()- lastMod)/60000);
  if(minutesAgo>15){return "<img src='images/redLight'/>";}
  else{return "img src='images/greenLight'/>";}
 }}
}


I want the red circle to show up if minutesAgo is greater than 15, otherwise the green circle should show.  I believe this is the correct code, but am not sure why it's not populating the grid.


Jon,

You were correct in your coding.  I missed a space between new and Date().getTime() which is why it was not showing the way I wanted it to.  Gotta love javascript coding!
0 Kudos