Vaadin 8 Grid: renderer for a client side timer in cell?

Hi,
is it possible to use some Grid 8 renderer for displaying active client side timers inside cells?
At first step, it seemed evident to me to take a look at AbstractJavaScriptRenderer, and I’ve implemented it’s “render” function in my JS connector:

[code]
com_example_MyJsRenderer = function () {

this.render = function (cell, data) {
cell.element.innerHTML = data;
}

}
[/code]which works perfectly. It correctly renders the column “as it is” to which MyJsRenderer has been attached to by grid.addColumn(…) method. However, any further development in such direction stucks at this point.
For instance, the following code

[code]
com_example_MyJsRenderer = function () {

var tick = 0;
var timerId = setInterval(function() {
tick++;
}, 1000);

this.render = function (cell, data) {
cell.element.innerHTML = (new Number(data) + tick);
}

}
[/code]runs the client side timer, but of course, cells are updated only when “render” is called.

Any other ideas?

Yes, you can use timers, but ofcourse with care. You should think cases where you need to stop the timer, i.e. not having runaway timers. As you render multilpe rows, each one will have timer etc. As an example I would recommend to check DeleteButtonRenderer from GridFastNavigation add-on. https://github.com/TatuLund/GridFastNavigation/blob/vaadin8/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/client/DeleteButtonRendererConnector.java

Thank you, Tatu, will definitely examine your DeleteButtonRendererConnector.

Here’s what I finally came to: a working sample of a vanilla Javascript connector for AbstractJavaScriptRenderer for an arbitrary column where each displayed cell value is updated at client side by means of a corresponding timer. Dynamically changing set of timers is managed in ‘render’ function with a help of a hashmap approach. The solution might be interesting in cases when it is desirable to get timely changing counters in cells /such as time values/, for instance, without the need to burden your backend data provider. Additional pros reside in the simplified integration of a pure JavaScript, which does not involve GWT programming, as well as widget set compilation is not needed.

[code]
com_example_MyJsRenderer = function () {

// defines TimerObject class
function TimerObject() {
this.id = null;
this.element = null;
}

// main timer for the whole renderer, running once a second
var mainTick = 0;
setInterval(function() {
// your logic here
mainTick++;
}, 1000);

// hashmap: key - cell.rowIndex, value - TimerObject
var timers = {};

function timersLength() {
var count = 0;
for (x in timers) {
count++;
}
return count;
}

// returns hashmap key i.e. cell.rowIndex if element was found in hashmap, else - null
function findElement(element) {
for (x in timers) {
if (timers
.element == element) {
return x;
}
}
return null;
}

// updates displayed value for certain TimerObject
function updateCellValue(timerObj, data) {
// your logic here
var val = new Number(data) + mainTick;
timerObj.element.innerHTML = ‘’ + val;
}

this.render = function (cell, data) {

// --- finds, stops and deletes from hashmap timers unused TimerObject
// where timerObj.element == cell.element ---
var key = findElement(cell.element);
if (key != null) {
  // TimerObject found, stops it
  clearInterval(timers[key]

.id);
// deletes TimerObject
delete timers[key]
;
}

var timerObj = null;

if (('' + cell.rowIndex) in timers) {
  // key - cell.rowIndex already exists in hashmap timers
  timerObj = timers['' + cell.rowIndex]

;
if (timerObj != null) {
// stops old timer attached to TimerObject
clearInterval(timerObj.id);
}
}

if (timerObj == null) {
  timerObj = new TimerObject();
}

timerObj.element = cell.element;
// attaches new timer to TimerObject
timerObj.id = setInterval(updateCellValue, 1000, timerObj, data);
// puts new/updated TimerObject to hashmap timers
timers['' + cell.rowIndex]

= timerObj;

console.log('##### - render: row = ' + cell.rowIndex + '; timers.length = ' + timersLength() + ' - #####');

};

}
[/code]Cheers!