Nov 12, 2014, 12:06 PM
The CellEditing plugin re-focus the view after editing. It causes resetting of scrolling.
Actually, the entire problem is the fact that IE resets scrolling on focus. It is specific to IE and it is quite a frustrating behavior.
So, likewise the previous override of the focusRow method, you can ignore re-focusing after editing.
I have to point here that backstage effects are possible. Due to override the focusRow method doesn't do its job in IE, i.e. it doesn't actually focus a row.
As for editing, the view is not refocused after editing. It means that, for example, navigating via arrow keys is not going to work, probably. Maybe, something else.
Well, these ramifications might be OK for you. If no, I suggest you to consider another approach - saving scrolling and restore when it is lost (i.e. after focusing). Unfortunately, it also have quite a big disadvantage. At first the scroll position resets, then it restores. Unfortunately, it doesn't happen immediately and it is flickering, shaking. I would say it annoys a lot.
So, as a summary there are two approaches.
1. Avoid re-focusing
Actually, the entire problem is the fact that IE resets scrolling on focus. It is specific to IE and it is quite a frustrating behavior.
So, likewise the previous override of the focusRow method, you can ignore re-focusing after editing.
Ext.grid.plugin.CellEditing.override({
onEditComplete : function(ed, value, startValue) {
var me = this,
activeColumn = me.getActiveColumn(),
context = me.context,
record;
if (activeColumn) {
record = context.record;
me.setActiveEditor(null);
me.setActiveColumn(null);
me.setActiveRecord(null);
context.value = value;
if (!me.validateEdit()) {
return;
}
if (!record.isEqual(value, startValue)) {
record.set(activeColumn.dataIndex, value);
}
if (!Ext.isIE) { // the fix
context.view.focus(false, true);
}
me.fireEvent('edit', me, context);
me.editing = false;
}
}
});
With that override the scroll doesn't jump to the begging.I have to point here that backstage effects are possible. Due to override the focusRow method doesn't do its job in IE, i.e. it doesn't actually focus a row.
As for editing, the view is not refocused after editing. It means that, for example, navigating via arrow keys is not going to work, probably. Maybe, something else.
Well, these ramifications might be OK for you. If no, I suggest you to consider another approach - saving scrolling and restore when it is lost (i.e. after focusing). Unfortunately, it also have quite a big disadvantage. At first the scroll position resets, then it restores. Unfortunately, it doesn't happen immediately and it is flickering, shaking. I would say it annoys a lot.
So, as a summary there are two approaches.
1. Avoid re-focusing
Ext.override(Ext.view.Table, {
focusRow: function (row, delay) {
var me = this,
row,
gridCollapsed = me.ownerCt && me.ownerCt.collapsed,
record;
if (me.isVisible(true) && !gridCollapsed && (row = me.getNode(row, true)) && me.el) {
me.scrollRowIntoView(row);
record = me.getRecord(row);
rowIdx = me.indexInStore(row);
me.selModel.setLastFocused(record);
if (!Ext.isIE) { // the fix
row.focus();
}
me.focusedRow = row;
me.fireEvent('rowfocus', record, row, rowIdx);
}
}
});
Ext.grid.plugin.CellEditing.override({
onEditComplete : function(ed, value, startValue) {
var me = this,
activeColumn = me.getActiveColumn(),
context = me.context,
record;
if (activeColumn) {
record = context.record;
me.setActiveEditor(null);
me.setActiveColumn(null);
me.setActiveRecord(null);
context.value = value;
if (!me.validateEdit()) {
return;
}
if (!record.isEqual(value, startValue)) {
record.set(activeColumn.dataIndex, value);
}
if (!Ext.isIE) { // the fix
context.view.focus(false, true);
}
me.fireEvent('edit', me, context);
me.editing = false;
}
},
cancelEdit: function() {
var me = this,
activeEd = me.getActiveEditor();
me.setActiveEditor(null);
me.setActiveColumn(null);
me.setActiveRecord(null);
if (activeEd) {
activeEd.cancelEdit();
if (!Ext.isIE) {
me.context.view.focus();
}
me.callSuper(arguments);
return;
}
// If we aren't editing, return true to allow the event to bubble
return true;
}
});
2. Restore scroll after focusExt.view.Table.override({
focusTask: new Ext.util.DelayedTask(),
focusRow: function (row, delay) {
var me = this,
row,
gridCollapsed = me.ownerCt && me.ownerCt.collapsed,
record;
if (delay) {
me.focusTask.delay(Ext.isNumber(delay) ? delay : 10, me.focusRow, me, [row, false]);
return;
}
me.focusTask.cancel();
if (me.isVisible(true) && !gridCollapsed && (row = me.getNode(row, true)) && me.el) {
me.scrollRowIntoView(row);
record = me.getRecord(row);
rowIdx = me.indexInStore(row);
me.selModel.setLastFocused(record);
me.focusedRow = row;
me.doFocus(row, record, rowIdx);
me.fireEvent("rowfocus", record, row, rowIdx);
}
},
doFocus: function(row, record, rowIdx, scrollLeft) {
var me = this,
saveScroll = Ext.isIE,
scrollLeft;
if (saveScroll) {
scrollLeft = me.el.getScrollLeft();
}
row.focus();
if (saveScroll) {
console.log("scrollLeft: " + scrollLeft);
me.el.setScrollLeft(scrollLeft);
me.ignoreScroll = false;
}
}
});
Ext.grid.plugin.CellEditing.override({
cancelEdit: function() {
var me = this,
activeEd = me.getActiveEditor();
me.setActiveEditor(null);
me.setActiveColumn(null);
me.setActiveRecord(null);
if (activeEd) {
activeEd.cancelEdit();
me.context.view.focusRow(me.context.rowIdx, 100);
me.callSuper(arguments);
return;
}
return true;
}
});
.Plugins(X.CellEditing()
.Listeners(events =>
{
events.BeforeEdit.Handler = "this.savedScrollLeft = e.grid.getView().el.getScrollLeft();";
events.Edit.Handler = "e.grid.getView().el.setScrollLeft(this.savedScrollLeft);";
events.Edit.Delay = 1;
})
)
By the way, I just tested the scenario with v3.0 beta and it appears to be working well. The scroll position doesn't reset and I don't see any flickering/shaking.