View Full Version : Programmatically adding and highlighting a row without refreshing whole grid

10 Oct 2013, 4:33 PM
I have a grid that needs to check for new data every several seconds and update the view accordingly. It's distracting to perform a full refresh because this displays a pulsing modal "Loading..." progress message over the grid with each poll. The behavior I need instead is to update the grid only when there is new data and to perform a fading highlight on it when the new row appears. To accomplish this I have an AJAX request that's performed with a setTimeout() which polls to see if any records on the backend have a timestamp newer than the most recent in my store. Then I call store.add(newRecords). I have the store listening for add events, which trigger a function to highlight the new rows, something like this:

for(var i = 0; i < records.length; i++) {
Ext.fly(grid.getView().getNode(records[i])).highlight("0000ff", { attr: 'color', duration: 2 });
Trouble is that when the add event fires, the rows have not yet been created in the grid, so the DOM query fails. In fact, it doesn't look like adding a new record to the store causes the grid DOM to update ever.

So the first question is: what am I missing that updating the store doesn't update the view?

And the second is: what event fires when the grid is completely done rendering in the browser? I've noticed that afterrender does *not* mean that the updated DOM is ready. I also don't see another event that fires after a change in the DOM has completed. As a result, I have had to perform operations that require the DOM is ready inside ugly and arbitrary setTimeout() blocks. I'm fairly new to Sencha, but I'm sure this is totally wrong.

Thanks for your help!

11 Oct 2013, 12:05 AM
you can add a listener to the grid view's refresh event to do the highlighting:

grid.getView().on('refresh', function() {
// highlight rows here

11 Oct 2013, 11:57 AM
No, refresh doesn't do it. If I set a breakpoint in the highlight function where it tries to select the new node in the DOM it is not present and I get an error. In other words: Ext.fly(grid.getView().getNode(newModelObj)) is undefined when the refresh event is fired so there's nothing to highlight.

14 Oct 2013, 2:04 AM
Try to listen for view#itemadd event for highlighting.

14 Oct 2013, 10:15 AM
No, adding new records to the store doesn't cause an 'itemadd' event to fire on the view, which gets back to the question I had about "hey, since this is MVC shouldn't the view be notified automatically when the model (store) is changed?" I'm guessing I'm missing something--maybe some configuration?--that properly wires the store and view together in this way.

Either that or Ext grids (v4.1.1) were simply never envisioned to handle "pushed" data updates, only ones "pulled" from within the control itself. That seems unlikely. I believe what I'm doing has probably been done many times before by others.

Nevertheless I'm about to do what I should not have to do with a toolkit like Ext: jam some unique id into the content of each column, wire up a DOM selector that walks up the tree to the parent row so the highlight function can find it, kick off a full refresh if new data is found during the AJAX pool, and perform the highlight after allowing a few hundred millis for the refresh to complete. Please stop me before I kill again! Ha ha!

15 Oct 2013, 12:40 AM
Have you setup a listener for gridview or for gridpanel?

15 Oct 2013, 8:02 AM
Is there any reason why that way of subscribing the grid view to listen for 'itemadd' should work differently from this:

grid.getView().on('itemadd', function() {
alert('Row added.');

15 Oct 2013, 8:14 AM
Well, that's mvc, so you should use control.
But both variants should work.

16 Oct 2013, 10:01 AM
I'm not using Ext.application. But then neither do the grid examples in the Sencha docs, so I'm not sure that's a problem.

For some reason while this does not capture 'itemadd' events:

grid.getView().on('itemadd', function() { alert('Row added.'); });

... this does:

grid = Ext.create('Ext.grid.Panel', {
viewConfig: {
stripeRows: true,
listeners: {
itemadd: function() {
alert('Row added.');

However, while the event is fired and the listener hears it, the view never updates with the added row as it does in your example, so there is nothing to highlight. Apparently calling store.add(newRecord) isn't a sufficient cause for the grid to display the new row. Which gets back to the first of the two problems that is keeping me from implementing this feature cleanly.

The next thing I figure I'm going to be asked is to provide a snippet of my code, which is reasonable, so how you create a fiddle in a reply like the one you made?

17 Oct 2013, 9:30 AM
Here's a fiddle that demonstrates what I'm seeing based on the Basic Array Grid example from the Sencha docs. This shows that 'itemadd' events fire on the view as expected when a record is added to the store, but you can still see that the new row is not being rendered in the grid.

http://jsfiddle.net/davidbeers/N9eRP/ (link should be good now)

17 Oct 2013, 10:35 PM
I can see 5 new empty rows. You may want to revisit the doc of add method (http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.data.Store-method-add) and change the arguments passed.