Nov 23, 2009, 6:38 AM
[CLOSED] [1.0] LockingGridView with custom drag-drop of rows
I'm trying to use the LockingGridView with a custom Plugin (from http://www.extjs.com/forum/showthread.php?t=21913). This plugin allows one or more rows to be re-ordered in the GridPanel by dragging and dropping them, however the LockingGridView doesn't seem to work when this Plugin is added.
I'm not sure how the LockingGridView works (I'm guessing it adds a separate Grid for each Locked column?), but do you know of a way I can get this following example working?
Any help would be much appreciated! Thanks,
Dan
ASPX page:
I'm not sure how the LockingGridView works (I'm guessing it adds a separate Grid for each Locked column?), but do you know of a way I can get this following example working?
Any help would be much appreciated! Thanks,
Dan
ASPX page:
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Collections.Generic"%>
<%@ Register assembly="Ext.Net" namespace="Ext.Net" tagprefix="ext" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
List<object> data = new List<object>();
for (int i = 0; i < 20; i++)
{
data.Add(new{Name="Rec "+i, Column1=i.ToString(), Column2=i.ToString()});
}
this.Store1.DataSource = data;
this.Store1.DataBind();
}
</script>
<!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">
<head id="Head1" runat="server">
<style type="text/css">
.grid-row-insert-below
{
border-bottom:1px solid #3366cc;
}
.grid-row-insert-above
{
border-top:1px solid #3366cc;
}
</style>
</head>
<body>
<form id="Form1" runat="server">
<ext:ResourceManager ID="ResourceManager1" runat="server" />
<ext:Store ID="Store1" runat="server">
<Reader>
<ext:JsonReader>
<Fields>
<ext:RecordField Name="Name" />
<ext:RecordField Name="Column1" />
<ext:RecordField Name="Column2" />
</Fields>
</ext:JsonReader>
</Reader>
</ext:Store>
<ext:GridPanel
ID="GridPanel1"
runat="server"
StoreID="Store1"
EnableDragDrop="true"
TrackMouseOver="true"
StripeRows="true"
Width="500"
Height="400"
Title="Drag row grid">
<ColumnModel>
<Columns>
<ext:Column Locked="true" ColumnID="Name" Header="Record Name" Width="200" DataIndex="Name" />
<ext:Column Header="Column 1" Width="300" DataIndex="Column1" />
<ext:Column Header="Column 2" Width="300" DataIndex="Column2" />
</Columns>
</ColumnModel>
<Plugins>
<ext:GenericPlugin ID="GenericPlugin1" runat="server" InstanceName="Ext.ux.dd.GridDragDropRowOrder">
<CustomConfig>
<ext:ConfigItem Name="scrollable" Value="true"></ext:ConfigItem>
</CustomConfig>
</ext:GenericPlugin>
</Plugins>
<View>
<ext:LockingGridView runat="server">
</ext:LockingGridView>
</View>
<SelectionModel>
<ext:RowSelectionModel ID="RowSelectionModel1" runat="server" />
</SelectionModel>
</ext:GridPanel>
<script src="GridOrdering.js" type="text/javascript"></script>
</form>
</body>
</html>
GridOrdering.js:Ext.namespace('Ext.ux.dd');
Ext.ux.dd.GridDragDropRowOrder = Ext.extend(Ext.util.Observable,
{
copy: false,
scrollable: false,
constructor : function(config)
{
if (config)
Ext.apply(this, config);
this.addEvents(
{
beforerowmove: true,
afterrowmove: true,
beforerowcopy: true,
afterrowcopy: true
});
Ext.ux.dd.GridDragDropRowOrder.superclass.constructor.call(this);
},
init : function (grid)
{
this.grid = grid;
grid.enableDragDrop = true;
grid.on({
render: { fn: this.onGridRender, scope: this, single: true }
});
},
onGridRender : function (grid)
{
var self = this;
this.target = new Ext.dd.DropTarget(grid.getEl(),
{
ddGroup: grid.ddGroup || 'GridDD',
grid: grid,
gridDropTarget: this,
notifyDrop: function(dd, e, data)
{
// Remove drag lines. The 'if' condition prevents null error when drop occurs without dragging out of the selection area
if (this.currentRowEl)
{
this.currentRowEl.removeClass('grid-row-insert-below');
this.currentRowEl.removeClass('grid-row-insert-above');
}
// determine the row
var t = Ext.lib.Event.getTarget(e);
var rindex = this.grid.getView().findRowIndex(t);
if (rindex === false || rindex == data.rowIndex)
{
return false;
}
// fire the before move/copy event
if (this.gridDropTarget.fireEvent(self.copy ? 'beforerowcopy' : 'beforerowmove', this.gridDropTarget, data.rowIndex, rindex, data.selections, 123) === false)
{
return false;
}
// update the store
var ds = this.grid.getStore();
// Changes for multiselction by Spirit
var selections = new Array();
var keys = ds.data.keys;
for (var key in keys)
{
for (var i = 0; i < data.selections.length; i++)
{
if (keys[key] == data.selections[i].id)
{
// Exit to prevent drop of selected records on itself.
if (rindex == key)
{
return false;
}
selections.push(data.selections[i]);
}
}
}
// fix rowindex based on before/after move
if (rindex > data.rowIndex && this.rowPosition < 0)
{
rindex--;
}
if (rindex < data.rowIndex && this.rowPosition > 0)
{
rindex++;
}
// fix rowindex for multiselection
if (rindex > data.rowIndex && data.selections.length > 1)
{
rindex = rindex - (data.selections.length - 1);
}
// we tried to move this node before the next sibling, we stay in place
if (rindex == data.rowIndex)
{
return false;
}
// fire the before move/copy event
/* dupe - does it belong here or above???
if (this.gridDropTarget.fireEvent(self.copy ? 'beforerowcopy' : 'beforerowmove', this.gridDropTarget, data.rowIndex, rindex, data.selections, 123) === false)
{
return false;
}
*/
if (!self.copy)
{
for (var i = 0; i < data.selections.length; i++)
{
ds.remove(ds.getById(data.selections[i].id));
}
}
for (var i = selections.length - 1; i >= 0; i--)
{
var insertIndex = rindex;
ds.insert(insertIndex, selections[i]);
}
// re-select the row(s)
var sm = this.grid.getSelectionModel();
if (sm)
{
sm.selectRecords(data.selections);
}
// fire the after move/copy event
this.gridDropTarget.fireEvent(self.copy ? 'afterrowcopy' : 'afterrowmove', this.gridDropTarget, data.rowIndex, rindex, data.selections);
return true;
},
notifyOver: function(dd, e, data)
{
var t = Ext.lib.Event.getTarget(e);
var rindex = this.grid.getView().findRowIndex(t);
// Similar to the code in notifyDrop. Filters for selected rows and quits function if any one row matches the current selected row.
var ds = this.grid.getStore();
var keys = ds.data.keys;
for (var key in keys)
{
for (var i = 0; i < data.selections.length; i++)
{
if (keys[key] == data.selections[i].id)
{
if (rindex == key)
{
if (this.currentRowEl)
{
this.currentRowEl.removeClass('grid-row-insert-below');
this.currentRowEl.removeClass('grid-row-insert-above');
}
return this.dropNotAllowed;
}
}
}
}
// If on first row, remove upper line. Prevents negative index error as a result of rindex going negative.
if (rindex < 0 || rindex === false)
{
this.currentRowEl.removeClass('grid-row-insert-above');
return this.dropNotAllowed;
}
try
{
var currentRow = this.grid.getView().getRow(rindex);
// Find position of row relative to page (adjusting for grid's scroll position)
var resolvedRow = new Ext.Element(currentRow).getY() - this.grid.getView().scroller.dom.scrollTop;
var rowHeight = currentRow.offsetHeight;
// Cursor relative to a row. -ve value implies cursor is above the row's middle and +ve value implues cursor is below the row's middle.
this.rowPosition = e.getPageY() - resolvedRow - (rowHeight/2);
// Clear drag line.
if (this.currentRowEl)
{
this.currentRowEl.removeClass('grid-row-insert-below');
this.currentRowEl.removeClass('grid-row-insert-above');
}
if (this.rowPosition > 0)
{
// If the pointer is on the bottom half of the row.
this.currentRowEl = new Ext.Element(currentRow);
this.currentRowEl.addClass('grid-row-insert-below');
}
else
{
// If the pointer is on the top half of the row.
if (rindex - 1 >= 0)
{
var previousRow = this.grid.getView().getRow(rindex - 1);
this.currentRowEl = new Ext.Element(previousRow);
this.currentRowEl.addClass('grid-row-insert-below');
}
else
{
// If the pointer is on the top half of the first row.
this.currentRowEl.addClass('grid-row-insert-above');
}
}
}
catch (err)
{
console.warn(err);
rindex = false;
}
return (rindex === false)? this.dropNotAllowed : this.dropAllowed;
},
notifyOut: function(dd, e, data)
{
// Remove drag lines when pointer leaves the gridView.
if (this.currentRowEl)
{
this.currentRowEl.removeClass('grid-row-insert-above');
this.currentRowEl.removeClass('grid-row-insert-below');
}
}
});
if (this.targetCfg)
{
Ext.apply(this.target, this.targetCfg);
}
if (this.scrollable)
{
Ext.dd.ScrollManager.register(grid.getView().getEditorParent());
grid.on({
beforedestroy: this.onBeforeDestroy,
scope: this,
single: true
});
}
},
getTarget: function()
{
return this.target;
},
getGrid: function()
{
return this.grid;
},
getCopy: function()
{
return this.copy ? true : false;
},
setCopy: function(b)
{
this.copy = b ? true : false;
},
onBeforeDestroy : function (grid)
{
// if we previously registered with the scroll manager, unregister
// it (if we don't it will lead to problems in IE)
Ext.dd.ScrollManager.unregister(grid.getView().getEditorParent());
}
});