views:

404

answers:

2

Hi,

I have a Dojo Datagrid in one of my pages (which contains more content) and the following problem occurs: As soon as I click on a column header to change the sorting, the page will jump up as if I clicked on some HTML-anchor.

Funny enough, the page jump will make the grid show only the first two rows after it jumped, instead of (e.g.) have the grid start at the top of the page after the jump, which is the expected behaviour if an anchor is used.

The problem occurs in different browsers (tested: Firefox 3.6, Opera 10, IE6), so I guess it might be a Dojo-problem/-bug.

Any ideas to make this annoying behaviour stop?

Greetings, Select0r

PS: this seems to describe a similar problem, only for JQuery (and unfortunately without a solution, too)

+2  A: 

There are a couple of forces at work in DataGrid and the underlying _Grid that can cause the grid to shrink to just the height of its header row between fetches, and then re-grow itself. If you're experiencing the behavior you've described specifically while scrolled to the bottom of your page, your browser is likely "scrolling up" (so that its viewport's bottom aligns with the new bottom of the page), but then when the table loads new data and resizes again, your browser is still "scrolled up".

I spent some time digging around DataGrid and _Grid. There are really two causes for this that I've found:

  1. DataGrid's _clearData function, which calls updateRowCount(0) (i.e. reducing the grid to 0 rows until the new results come in)

  2. _Grid's _resize function, which sets its viewsNode's height style to '' if _autoHeight is true (which seems to be the case if either autoHeight is true, or is a number >= rowCount)

If you're not averse to messing with the source, you could simply remove one line of code from DataGrid._clearData and another one from _Grid._resize and be done with it; assuming you'd like a cleaner approach, however, I've attempted to subclass DataGrid with a couple of workarounds instead. See how this fares for you.

dojo.provide('my.DataGrid');

dojo.declare('my.DataGrid', dojox.grid.DataGrid, {
  updateRowCount: function(inRowCount) {
    if (inRowCount > 0) { //ignore requests to set rowCount to 0
      this.inherited(arguments);
    }
  },
  _resize: function(changeSize, resultSize) {
    if (this._autoHeight) {
      //sizeblink workaround
      var _viewsNode = this.viewsNode;
      this.viewsNode = {style: {height: ''}}; //_Grid._resize crash dummy
      this.inherited(arguments);
      this.viewsNode = _viewsNode;
      //call post-functions again with node properly hooked
      this.adaptWidth();
      this.adaptHeight();
      this.postresize();
    } else {
      this.inherited(arguments);
    }
  }
});
//carry over DataGrid's custom markupFactory, otherwise declarative won't work
my.DataGrid.markupFactory = dojox.grid.DataGrid.markupFactory;

Hope it helps, or at least provides insight. I wonder if this issue ought to be entered as a bug in dojo's trac...

Ken
We found out that the resetting of the DataGrid was the problem to focus on and found a workaround in the meantime (see my answer), but your solution is definitely favoured (even if I haven't tried it yet, but will soon). Thanks a lot!
Select0r
I'd like to mark you answer as the accepted one, but SO won't let me ...
Select0r
I think it's because you set a bounty but it expired before you got to mark it. I admit I was pretty close to the deadline of the bounty so I wasn't really expecting to get it ;) If it did end up working for you, then I'm glad it helped.
Ken
A: 

Here's a quick&dirty workaround: as CnEY evaluated, the problem is the DataGrid resetting itself to 0 rows and then filling itself again with data.

If you enclose the DataGrid with a DIV that has a min-height of the grids height, then the resetting will not influence the page's height and therefore the "jumping" will stop.

Of course, this is just a basic workaround as the surrounding DIV's height is somewhat static even if set/changed with JavaScript, so I'd rather go with something dynamic (as the solution posted by CnEY).

Select0r