Search code examples
javascriptjquerykendo-uikendo-gridkendo-asp.net-mvc

How to select the row in KendoGrid having time column value closest to current time (not date)?


I have a Kendo grid in which one column has appointment time. On Grid load I want to select the row which has time closest to the current time.

For Example Kendo grid has four rows and each row has following value in Appointment time column: 09:30 AM, 10:30 AM, 11:30 AM, 12:30 AM

and current time is 11:00 AM. Now on page load, the row having time as 11:30 AM should get selected.

If we load the grid on 12:00 AM then the row having 12:30 AM should get selected.

And if we load the grid after 12:30 AM then last row of grid should get selected since it'll be closest to the current time:

My current code to select the row looks as follows:

Kendo Grid ID: dgListView

Kendo Column

{
        field: "ApptTime",
        hidden: true,
        template: function (dataItem) {
            return kendo.toString(dataItem.ApptTime, "hh:mm tt")
        },
        attributes: {
            ApptTime: "ApptTime"
        }
    }

Function on databound

function SetGridRowSelected(e) {
var objGrid = jQuery_1_9_1('#dgListView');
var row;
var currentDate = new Date();

var time = currentDate.toLocaleTimeString();

var data = objGrid.data("kendoGrid");

row = data.tbody.find(">tr:not(.k-grouping-row)").filter(function (i) {
    return (this.cells[18].innerHTML >= time); //18th column in Grid has appointment time
});

if (objGrid && row.length) {
    data.select(row);
    row.click();
    row.addClass('k-state-selected');
}

var scrollContentOffset = grid.find("tbody").offset().top;
var selectContentOffset = data.select().offset().top;
var distance = selectContentOffset - scrollContentOffset;
grid.find(".k-grid-content").animate({
    scrollTop: distance
}, 500);
}

I'm comparing the 18th column (it has appointment time) with the current time and trying to select the row which is closest to it but comparison is not happening and it's not throwing any error.


Solution

  • See the whole example at this Dojo

    The time within a day can be computed using epoch time modulus milliseconds in a day math

    date.getTime() % 86400000
    

    As a page is view the current time is always changing, so you will need to possibly change which row is to be selected

            setInterval(function() {
              // note: nowModel is an observable bound to a displayed element
              nowModel.set('now', new Date());
              select_row_next_closest_by_time();
            }, 1000);  
    

    Selecting the next (forward time) closest to current time requires searching through the data of the grid view.

            var seluid;
            function select_row_next_closest_by_time() {
              var grid = $("#grid").data("kendoGrid");
              var v = grid.dataSource.view();
              var msn = nowModel.get('now').getTime() % 86400000;
              
              var minuid="", mindiff = Number.MAX_SAFE_INTEGER;
              // scan the view data to find next nearest time point
              for (var index=0; index < v.length; index++) {
                 var ms = v[index].get('Date').getTime() % 86400000;
                 var diff = ms - msn;
                 if (diff < 0) diff += 86400000;  // for wrap around
                 if (diff < mindiff) {
                   mindiff = diff;                // first next closest in time
                   minuid = v[index].uid;
                 }
              }
    
              if (seluid != minuid) {
                // change selection
                if (seluid) { 
                  grid.tbody.find('tr[data-uid="'+seluid+'"]').removeClass('k-state-selected');
                }
                grid.select(grid.tbody.find('tr[data-uid="'+minuid+'"]'));
                seluid = minuid;
              }
            }
          });
    

    Alternate way

    Go here for example Dojo

    Presuming the grid data is presorted by Date, and all the rows in the grid are for the same day, use .find() and .indexOf() methods to determine which row should be selected. Of course the methods use looping behind the scene.

            var view = $("#grid").data("kendoGrid").dataSource.view();
    
            nowt = (new Date()).getTime() % 86400000; 
            
            var
              pick = view.find(row => (row.Date.getTime() % 86400000) >= nowt),
              pickIndex = (pick === undefined) ? view.length-1 : view.indexOf(pick)
            ;
            
            $("#grid").data("kendoGrid").select("tr:eq("+pickIndex+")");