PDA

View Full Version : [Solved] Inline editor in an EditorGrid is always at the first row in Opera.



MaximGB
9 Aug 2007, 2:04 PM
Hi.

I've tried to find the solution but failed, now reporting it here:
- Inline editor in an EditorGrid is always at the first row in Opera.

1. Ext version 1.1
2. Adapter ext-base.js (and others tested too)
3. windows(xp sp2)
4. browser - Opera 9.1. then 9.22
5. code snippet:


<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru" lang="ru">
<head>
<title>Storage test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="resources/css/ext-all.css" />
<script type="text/javascript" src="adapter/ext/ext-base.js"> </script>
<script type="text/javascript" src="ext-all-debug.js"> </script>
</head>
<body>
<script type="text/javascript">//<![CDATA[
Ext.onReady(function() {
var toolbar_el = Ext.DomHelper.append(document.body, {tag: 'div', id: 'toolbar'});
var toolbar = new Ext.Toolbar(toolbar_el, [
{
text: 'Add',
handler: onAddButtonClick
},
{
text: 'Edit',
handler: onEditButtonClick
},
{
text: 'Delete',
handler: onDeleteButtonClick
},
{
text: 'Filter',
handler: onFilterButtonClick
},
{
text: 'Reset filter',
handler: onResetFilterButtonClick
},
'-',
{
text: 'Commit',
handler: onCommitButtonClick
},
{
text: 'Reject',
handler: onRejectButtonClick
}
]);

var data = [];
for (var i = 0; i < 10; i++) {
data.push({title: 'line-'+i});
}

var grid_el = Ext.DomHelper.append(document.body, {tag: 'div', id: 'grid', style: 'border: 1px solid #D0DEF0;'});
var grid = new Ext.grid.EditorGrid(grid_el, {
ds: new Ext.data.Store({
proxy: new Ext.data.MemoryProxy(data),
reader: new Ext.data.JsonReader({}, [
{name: 'title'}
]),
sortInfo: {field: 'title', dir: 'DESC'}
}),
cm: new Ext.grid.ColumnModel([
{
header: 'Title',
dataIndex: 'title',
sortable: true,
editor: new Ext.grid.GridEditor(
new Ext.form.TextField({

}),
{

}
)
}
]),
autoSizeColumns: true
});
grid.getDataSource().load();
grid.render();

var filter = '';

function onAddButtonClick()
{
Ext.Msg.prompt('Add', 'Input value', function(btn, text) {
if (btn == 'ok') {
var ds = grid.getDataSource();
var rt = ds.recordType;
ds.clearFilter(true);
ds.add(new rt({title: text}));
ds.applySort();
ds.filter('title', filter);
}
});
}

function onEditButtonClick()
{
var rc = grid.getSelectionModel().getSelected();
if (rc) {
Ext.Msg.prompt('Edit ' + rc.get('title'), 'Input value', function(btn, text) {
if (btn == 'ok') {
rc.set('title', text);
}
});
}
}

function onDeleteButtonClick()
{
var rc = grid.getSelectionModel().getSelected();
if (rc) {
var ds = grid.getDataSource();
ds.clearFilter(true)
ds.remove(rc);
ds.filter('title', filter);
}
}

function onFilterButtonClick()
{
Ext.Msg.prompt('Filter', 'Input value', function(btn, text) {
if (btn == 'ok') {
filter = text;
grid.getDataSource().filter('title', text);
}
});
}

function onResetFilterButtonClick()
{
filter = '';
grid.getDataSource().clearFilter();
}

function onCommitButtonClick()
{
grid.getDataSource().commitChanges();
}

function onRejectButtonClick()
{
grid.getDataSource().rejectChanges();
}
});
//]]></script>
</body>
</html>

6. FireBug stacktrace - no bugs thrown
7. screenshot - see below

MaximGB
10 Aug 2007, 12:43 AM
The bug source is in the Ext.lib.Dom.getXY() :( continue investigation...

MaximGB
10 Aug 2007, 1:23 AM
Hi, I've probably solved the bug.

I've changed the last 10 lines of code in Ext.lib.Dom.getXY():
Were:


...
p = el.parentNode;
while (p && p != bd) {
if (!(Ext.isOpera && p.tagName != 'TR' && fly(p).getStyle("display") != "inline")) {
x -= p.scrollLeft;
y -= p.scrollTop;
}
p = p.parentNode;
}
return [x, y];


Changes:


...
p = el.parentNode;
while (p && p != bd) {
if (!(Ext.isOpera && p.tagName == 'TR') && fly(p).getStyle("display") != "inline") {
x -= p.scrollLeft;
y -= p.scrollTop;
}
p = p.parentNode;
}
return [x, y];


I've tested the code in IE6, FF2.0.0.6, Opera 9.22 with various margins and position types.


<!-- I have tested the grid creation in following containers -->
<div id='grid' style="height: 300px; margin-top: 1200px"> </div>
...
<div id='grid' style="position: relative; height: 300px; margin-top: 65px; top: 800px; left: 45px"> </div>
...
<div id='grid' style="position: absolute; height: 300px; width: 500px; left: 200px; top: 400px"> </div>
-->

it seems to work ;), but expert check needed.

-- Edit
No, not solved... my code returns wrong horizontal position.

-- Edit
No, my code is probably ok, and I've found another positioning bug.

For example, try to open Editor Grid example from the docs in Opera, then size the grid columns such that horizontal grid scroll bar appeared, then scroll to the middle in the horizontal axis, then size any column. The header and the column content won't be in sync, but when you scroll again the sync will be restored.

jack.slocum
10 Aug 2007, 10:31 AM
This is fixed in SVN.

MaximGB
10 Aug 2007, 11:50 PM
While the fixes are not public, I suggest the following patch:


if (Ext.isOpera) {
Ext.override(Ext.Element, {
getXY: function()
{
var fly = Ext.fly;
var p, pe, b, scroll, bd = document.body;
//el = Ext.getDom(el);
el = this.dom;

if (el.getBoundingClientRect) {
b = el.getBoundingClientRect();
scroll = fly(document).getScroll();
return [b.left + scroll.left, b.top + scroll.top];
}

var x = 0, y = 0;
p = el;
var hasAbsolute = fly(el).getStyle("position") == "absolute";

while (p) {
x += p.offsetLeft;
y += p.offsetTop;

if (!hasAbsolute && fly(p).getStyle("position") == "absolute") {
hasAbsolute = true;
}

if (Ext.isGecko) {
pe = fly(p);
var bt = parseInt(pe.getStyle("borderTopWidth"), 10) || 0;
var bl = parseInt(pe.getStyle("borderLeftWidth"), 10) || 0;
x += bl;
y += bt;
if (p != el && pe.getStyle('overflow') != 'visible') {
x += bl;
y += bt;
}
}
p = p.offsetParent;
}

if (Ext.isSafari && hasAbsolute) {
x -= bd.offsetLeft;
y -= bd.offsetTop;
}

if (Ext.isGecko && !hasAbsolute) {
var dbd = fly(bd);
x += parseInt(dbd.getStyle("borderLeftWidth"), 10) || 0;
y += parseInt(dbd.getStyle("borderTopWidth"), 10) || 0;
}

p = el.parentNode;
while (p && p != bd) {
if (!(Ext.isOpera && p.tagName == 'TR')) {
x -= p.scrollLeft;
y -= p.scrollTop;
}
p = p.parentNode;
}
return [x, y];
}
});
}