PDA

View Full Version : How can I save new rows order in a Grid?



maya
26 May 2007, 11:57 PM
Hi,

I enable users to change the rows' order within a grid.
After the user changes the rows order I need to save this new order in a database.

I have two problems in doing that:
1. How can I define a loop for all rows in the grid? (I can use the RowSelectionModel.selectAll(); and then the RowSelectionModel.getSelections() - but this is not very elegant).

2. More important: How can I attach ids to each row?
In order to save the new rows order I defined hidden form fields with name=<the object's id in my database>. Before saving the new order (submitting the form), I need to build a loop, go over all rows, and update their new order in the hidden form fields. BUT: How can I attach an object's id to the Grid rows?

Thanks,
Maya

Animal
27 May 2007, 12:29 AM
You pass the object's id in the database to the browser, and capture it in the Record definition.

Every Record in a Store has an id. if You don't pass one from the server, and capture it in your Record definition, Ext will generate one for you.

maya
27 May 2007, 12:46 AM
Thanks for your reply, Animal.

I have 2 problems with this method:

1. In order to save the new order I need to select all rows in their new order.
When I select all rows using the following code, the rows order is the initial order, and not the new order, after the user changed their order by dragging and dropping rows:

var sm = grid.getSelectionModel();
sm.selectAll();
var rows = sm.getSelections();
for(i = 0; i < rows.length; i++) {
...
}

It seems like the grid.getSelectionModel() is not updated with the new rows order. What object is updated with the new order?

2. Can you give an example of how to define a record's id?
I create my rows in the following way:
var myData = [
['3m Co',71.72,0.02,0.03,'9/1 12:00am'],
['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am'],
['Altria Group Inc',83.81,0.28,0.34,'9/1 12:00am'],
['American Express Company',52.55,0.01,0.02,'9/1 12:00am']
];
How can I define their id?

Thanks,
Maya

Animal
27 May 2007, 1:00 AM
Are you implementing DnD yourself inside a Grid to move rows?

How are you doing that?

Remember that data comes fom the Grid's Store, not the View.

If you want to reorder Records, you must reorder the Store, then fire the Store's datachanged event so that the View updates itself.

maya
27 May 2007, 1:34 AM
Hi Animal,

1. Pls. find enclosed my code.
2. I am implementing DnD myself inside a Grid to move rows - because it didn't work out of the box by defining: "enableDragDrop: true" in the Grid object (am I missing something?). The only problem with this DnD implementation is that it disables the columns DnD that worked before (when defining "var ddrow = new Ext.dd.DropTarget(...) - the columns DnD is disabled).
3. Can you please give a code example for your suggestion based on the code I sent (how to "reorder the Store, then fire the Store's datachanged event so that the View updates itself").

Thanks,
Maya
--------------------
my code:

<form name="myForm" method="post" action="(the form's handler)">
<script type="text/javascript" language="javascript">
function updateNewRowsOrder()
{
var sm = grid.getSelectionModel();
sm.selectAll();
var rows = sm.getSelections();
var feName;
for(i = 0; i < rows.length; i++) {
rowID = rows[i].get('grid_id');
feName = "in_order"+rowID;
document.myForm.elements[feName].value = i;
}
}
</script>
<input type="hidden" name="in_order601" value="1"><input type="hidden" name="in_order2624" value="2"><input type="hidden" name="in_order2017" value="3"><input type="hidden" name="in_order2623" value="4"><input type="hidden" name="in_order2086" value="5"><input type="hidden" name="in_order2299" value="6"><input type="hidden" name="in_order562" value="7"><input type="hidden" name="in_order2261" value="8">

<!-- a place holder for the grid. requires the unique id to be passed in the javascript function, and width and height ! -->
<div id="grid_panel" style="width:'100%';height: expression(document.body.clientHeight-this.getBoundingClientRect().top);">
<div id="grid_table"></div>
<div id="GridDD" style="margin-top: 50px;"></div>
</div>
<script type="text/javascript">
var grid;
var Example = {
init : function(){
// some data yanked off the web
var myData = [
['1','[G]','<a name="601" href="myPhp.php?pr_id=601" title="myTitle" ></font></a>','601'],
['2','[G]','<a name="2624" href="myPhp.php?pr_id=2624" title="myTitle" ><font color="#000000"> Create Business Groups</font></a>','2624'],
['3','[G]','<a name="2017" href="myPhp.php?pr_id=2017" title="myTitle" ><font color="#000000"> Define Organizations and Organization Structures</font></a>','2017'],
['4','[G]','<a name="2623" href="myPhp.php?pr_id=2623" title="myTitle" ><font color="#000000"> Define Locations</font></a>','2623'],
['5','[G]','<a name="2086" href="myPhp.php?pr_id=2086" title="myTitle" ><font color="#000000"> Define Positions</font></a>','2086'],
['6','[G]','<a name="2299" href="myPhp.php?pr_id=2299" title="myTitle" ><font color="#000000"> Job Evaluation</font></a>','2299'],
['7','[G]','<a name="562" href="myPhp.php?pr_id=562" title="myTitle" ><font color="#000000"> Plan HR Budgets</font></a>','562'],
['8','[G]','<a name="2261" href="myPhp.php?pr_id=2261" title="myTitle" ><font color="#000000"> Define Grades and Payroll Information</font></a>','2261']];

var ds = new Ext.data.Store({
proxy: new Ext.data.MemoryProxy(myData),
reader: new Ext.data.ArrayReader({id: 0}, [
{name: 'grid_auto_num'},{name: 'grid_gl'},{name: 'grid_name'},{name: 'grid_id'} ])
});
ds.load();

// the DefaultColumnModel expects this blob to define columns. It can be extended to provide
// custom or reusable ColumnModels
var colModel = new Ext.grid.ColumnModel([
{header: '#', width:15 , sortable: true, locked:false, dataIndex: 'grid_auto_num'},
{header: 'G/L', width:25 , sortable: true, locked:false, dataIndex: 'grid_gl'},
{header: 'Process name', width:200 , sortable: true, locked:false, dataIndex: 'grid_name'},
{header: 'ID', width:32 , sortable: true, locked:false, dataIndex: 'grid_id'}]);

// create the Grid
grid = new Ext.grid.Grid('grid_table', {
ds: ds,
cm: colModel,
enableColumnMove: false,
autoSizeColumns: true,//Columns are resized to fit their content on initial render.
autoSizeHeaders: false,//Headers are resized according to the column's data (if the data is short and the header is long - the column becomes short).
//The "enableRowHeightSync" causes the locked rows to be in the same height as the non-locked rows.
enableRowHeightSync: true,
trackMouseOver: true,
minColumnWidth: 12
,enableDragDrop: true
});

//Code that enables D&D of rows.
var ddrow = new Ext.dd.DropTarget(grid.container, {
ddGroup : 'GridDD',
copy:false,
notifyDrop : function(dd, e, data){
var sm=grid.getSelectionModel();
var rows=sm.getSelections();
var cindex=dd.getDragData(e).rowIndex;
for(i = 0; i < rows.length; i++) {
rowData=ds.getById(rows[i].id);
if(!this.copy){
ds.remove(ds.getById(rows[i].id));
}
ds.insert(cindex,rowData);
};
}
});
//End of: Code that enables D&D of rows.
var layout = Ext.BorderLayout.create({
center: {
margins:{left:0,top:0,right:0,bottom:0},
panels: [new Ext.GridPanel(grid)]
}
}, 'grid_panel');

grid.render();

//grid.getSelectionModel().selectFirstRow();
}
};
Ext.onReady(Example.init, Example, true);

</script></form>

Animal
27 May 2007, 1:40 AM
You're manipulating the Store, so that will update the View. That's good.

What's the problem?

maya
27 May 2007, 1:42 AM
I forgot to add to the code sample I sent the form's submit button.

This save button calls to:
"updateNewRowsOrder(); document.myForm.submit();" on its "onclick" event.

Thanks,
Maya

maya
27 May 2007, 1:47 AM
The problem is that the following loop (on the var rows) goes over the initial rows order and not the new one.

var sm = grid.getSelectionModel();
sm.selectAll();
var rows = sm.getSelections();
var feName;
for(i = 0; i < rows.length; i++) {
rowID = rows[i].get('grid_id');
feName = "in_order"+rowID;
document.myForm.elements[feName].value = i;
}

Animal
27 May 2007, 1:48 AM
You want to pass something to do with Grid rows back to the server????

Just collect params from the Store, and use an Ext.data.Connection to send info to the server.

maya
27 May 2007, 2:30 AM
My problem is how to collect the new order from the Store? I can collect the initial order but not the new order after the rows were DnD-ed.

Animal
27 May 2007, 7:40 AM
I think you're doing something wrong.

For a start, look at your notifyDrop.

You are looping upwards through the selections, inserting each one at the same index, won't that reverse the order?

But then you're removing each one before reinserting, so your insertion point will be one out.

But The order of Records in the Store should be whatever you set it to.

Take a look at the results of



ds.getRange(0, ds.getCount() - 1);


or loop through the Records using



ds.each(function(rec){...});

amackay11
27 May 2007, 10:09 AM
Maya,

I have a working DnD grid, that does re-order. My data has a hidden 'SeqNumber' field. I am no javascript expert so following code may not be most efficient...but it works


var drop = new Ext.dd.DropTarget(grdPaging.container, {
ddGroup : 'GridDD',
notifyDrop : function(dd, e, data){
var sm=rowsel_model;
var rows=sm.getSelections(); // source drag
if ( dd.getDragData(e).selections == null ) {
Ext.MessageBox.alert ('Error','Invalid drop area'); // bad destination
return
}
var destdrag = sm.selections.items[0].data.SeqNumber-1; // row index in the grid.
var sourcedrag = rows[0].id;
ds.remove(rows[0]); // remove source row
ds.insert(destdrag, rows); // add back to ds in destination location.

ds_reorder(); // reorder all the records.
rowsel_model.selectRow(destdrag); // select the destination drop row

... call server to update the order .........
}
});

// function to loop through datastore, and update sequence numbers (1 to n)

function ds_reorder () {

for (var i = 0, j=1, len = ds.data.length; i < len; i++, j++ ){
if (ds.data.items[i].get('SeqNumber') != j ) {
ds.data.items[i].set('SeqNumber',j);
}

}

KGL
17 Jan 2008, 11:42 PM
Hi @all,

I use mayas example. That works fine (Thanks a lot !!!!)

But now I want to load dynamic data from the database with an httpproxy and jsonreader (that works fine in another example). So if these code examples:



<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>DnD Example</title>

<link rel="stylesheet" type="text/css" href="../js/extjs/resources/css/ext-all.css" />

<script src="http://www.google-analytics.com/urchin.js" type="text/javascript"> </script><script type="text/javascript">_uacct = "UA-1396058-1";urchinTracker();</script>
<link rel="stylesheet" type="text/css" href="../js/extjs/resources/css/xtheme-default.css" /><!-- LIBS -->
<script type="text/javascript" src="../js/extjs/adapter/ext/ext-base.js"></script>

<!-- ENDLIBS -->

<script type="text/javascript" src="../js/extjs//ext-all-debug.js"></script>


<script type="text/javascript" src="RowExpander.js"></script>
<link rel="stylesheet" type="text/css" href="grid-examples.css" />

<!-- Common Styles for the examples -->
<link rel="stylesheet" type="text/css" href="../examples.css" />

<style type="text/css">
body .x-panel {
margin-bottom:20px;
}
.icon-grid {
background-image:url(../shared/icons/fam/grid.png) !important;
}
#button-grid .x-panel-body {
border:1px solid #99bbe8;
border-top:0 none;
}
.add {
background-image:url(../shared/icons/fam/add.gif) !important;
}
.option {
background-image:url(../shared/icons/fam/plugin.gif) !important;
}
.remove {
background-image:url(../shared/icons/fam/delete.gif) !important;
}
.save {
background-image:url(../shared/icons/save.gif) !important;
}
</style>
</head>
<body>
<form name="myForm" method="post" action="(the form's handler)">
<script type="text/javascript" language="javascript">
function updateNewRowsOrder(){
var sm = grid.getSelectionModel();
sm.selectAll();
var rows = sm.getSelections();
var feName;
for(i = 0; i < rows.length; i++) {
rowID = rows[i].get('FlexField04');
feName = "in_order"+rowID;
document.myForm.elements[feName].value = i;
}
}
</script>
<input type="hidden" name="in_order601" value="1"><input type="hidden" name="in_order2624" value="2"><input type="hidden" name="in_order2017" value="3"><input type="hidden" name="in_order2623" value="4"><input type="hidden" name="in_order2086" value="5"><input type="hidden" name="in_order2299" value="6"><input type="hidden" name="in_order562" value="7"><input type="hidden" name="in_order2261" value="8">

<!-- a place holder for the grid. requires the unique id to be passed in the javascript function, and width and height ! -->
<div id="grid_panel" style="width:'100%';height: expression(document.body.clientHeight-this.getBoundingClientRect().top);">
<div id="grid_table"></div>
<div id="GridDD" style="margin-top: 50px;"></div>
</div>
<script type="text/javascript">
var grid;
var colModel;
// build arrays with attributes for the columns
var aColumnHeader = ["ID","Art","Adresse","Datum","Ansprechpartner"];
var aDataIndex = ["FlexField01","FlexField02","FlexField03","FlexField04","FlexField05"];
var aColumnWidth = [70,100,200,100,150];

var Example = {
init : function(){
// some data yanked off the web
var myFriends = [
['1','[G]','<a name="601" href="myPhp.php?pr_id=601" title="myTitle" ></font></a>','601'],
['2','[G]','<a name="2624" href="myPhp.php?pr_id=2624" title="myTitle" ><font color="#000000"> Create Business Groups</font></a>','2624'],
['3','[G]','<a name="2017" href="myPhp.php?pr_id=2017" title="myTitle" ><font color="#000000"> Define Organizations and Organization Structures</font></a>','2017'],
['4','[G]','<a name="2623" href="myPhp.php?pr_id=2623" title="myTitle" ><font color="#000000"> Define Locations</font></a>','2623'],
['5','[G]','<a name="2086" href="myPhp.php?pr_id=2086" title="myTitle" ><font color="#000000"> Define Positions</font></a>','2086'],
['6','[G]','<a name="2299" href="myPhp.php?pr_id=2299" title="myTitle" ><font color="#000000"> Job Evaluation</font></a>','2299'],
['7','[G]','<a name="562" href="myPhp.php?pr_id=562" title="myTitle" ><font color="#000000"> Plan HR Budgets</font></a>','562'],
['8','[G]','<a name="2261" href="myPhp.php?pr_id=2261" title="myTitle" ><font color="#000000"> Define Grades and Payroll Information</font></a>','2261']
];

var xg = Ext.grid;

var ds = new Ext.data.Store({
proxy: new Ext.data.MemoryProxy(myFriends),
reader: new Ext.data.ArrayReader({id: 0}, [{name: 'FlexField01'},{name: 'FlexField02'},{name: 'FlexField03'},{name: 'FlexField04'} ])
});
ds.load();

ds2 = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({url: 'getOrder.php'}),
reader: new Ext.data.JsonReader({
root: 'myFriends',
totalProperty: 'totalCount',
id: 'id'
},
[
{name: 'FlexField01', mapping: 'FlexField01', type: 'string'},
{name: 'FlexField02', mapping: 'FlexField02', type: 'string'},
{name: 'FlexField03', mapping: 'FlexField03', type: 'string'},
{name: 'FlexField04', mapping: 'FlexField04', type: 'string'},
{name: 'FlexField05', mapping: 'FlexField05', type: 'string'}
])
});

ds2.load();

// the DefaultColumnModel expects this blob to define columns. It can be extended to provide
// custom or reusable ColumnModels
colModel = new Ext.grid.ColumnModel([
{header: 'Dummy', dataIndex: 'Dummy', sortable: true},
{header: 'Dummy', dataIndex: 'Dummy', sortable: true},
{header: 'Dummy', dataIndex: 'Dummy', sortable: true},
{header: 'Dummy', dataIndex: 'Dummy', sortable: true},
{header: 'Dummy', dataIndex: 'Dummy', sortable: true}
]);

columnAdd();

// create the Grid
grid = new Ext.grid.GridPanel({
ds: ds,
cm: colModel,
enableColumnMove: false,
autoSizeColumns: true,//Columns are resized to fit their content on initial render.
autoSizeHeaders: false,//Headers are resized according to the column's data (if the data is short and the header is long - the column becomes short).
enableRowHeightSync: true,
trackMouseOver: true,
minColumnWidth: 12,
enableDragDrop: true,
renderTo: 'grid_table'
});

//Code that enables D&D of rows.
var ddrow = new Ext.dd.DropTarget(grid.container, {
ddGroup : 'GridDD',
copy:false,
notifyDrop : function(dd, e, data){
var sm=grid.getSelectionModel();
var rows=sm.getSelections();
var cindex=dd.getDragData(e).rowIndex;
for(i = 0; i < rows.length; i++) {
rowData=ds.getById(rows[i].id);
if(!this.copy){
ds.remove(ds.getById(rows[i].id));
}
ds.insert(cindex,rowData);
};
}
});

grid.render();

//grid.getSelectionModel().selectFirstRow();
}
};
Ext.onReady(Example.init, Example, true);


function columnAdd(){
//initionalization of columns.
for (var i=0; i<5;i++)
{
colModel.setColumnHeader(i,aColumnHeader[i]);
colModel.setDataIndex(i,aDataIndex[i]);
colModel.setColumnWidth(i,aColumnWidth[i]);
}
}
</script></form>


getOrder.php delivers the following data:


{"myFriends":[{"FlexField01":"1","FlexField02":"Ableseung","FlexField03":"Pascalstr. 1,10587 Berlin","FlexField04":"2007-12-01","FlexField05":"Conny Reimann\r"},{"FlexField01":"17","FlexField02":"Instandsetzung","FlexField03":"Bismaarckstr. 6,10583 Berlin","FlexField04":"2007-12-01","FlexField05":"Martina Glagow\r"},{"FlexField01":"18","FlexField02":"Ableseung","FlexField03":"Pascalstr. 7,10587 Berlin","FlexField04":"2007-12-01","FlexField05":"Magdalena Neuer\r"},{"FlexField01":"19","FlexField02":"Instandsetzung","FlexField03":"Bismaarckstr. 7,10583 Berlin","FlexField04":"2007-12-01","FlexField05":"Kati Wilhelm\r"},{"FlexField01":"20","FlexField02":"Inkasso","FlexField03":"Otto-Suhr-Allee 1,10585 Berlin","FlexField04":"2007-12-01","FlexField05":"Katrin Apel\r"},{"FlexField01":"21","FlexField02":"Ableseung","FlexField03":"Pascalstr. 8,10587 Berlin","FlexField04":"2007-12-01","FlexField05":"Michi Greis\r"},{"FlexField01":"22","FlexField02":"Instandsetzung","FlexField03":"Bismaarckstr. 8,10583 Berlin","FlexField04":"2007-12-01","FlexField05":"Sven Fischer\r"},{"FlexField01":"23","FlexField02":"Ableseung","FlexField03":"Pascalstr. 9,10587 Berlin","FlexField04":"2007-12-01","FlexField05":"Rico Gross\r"},{"FlexField01":"24","FlexField02":"Ausschaltung","FlexField03":"Ernst-Reuter-Platz 5,10589 Ber","FlexField04":"2007-12-01","FlexField05":"Michael R"},{"FlexField01":"25","FlexField02":"Instandsetzung","FlexField03":"Bismaarckstr. 9,10583 Berlin","FlexField04":"2007-12-01","FlexField05":"Franz Beckenbauer\r"},{"FlexField01":"26","FlexField02":"Ableseung","FlexField03":"Pascalstr. 10,10587 Berlin","FlexField04":"2007-12-01","FlexField05":"Petra Angerer\r"},{"FlexField01":"27","FlexField02":"Inkasso","FlexField03":"Otto-Suhr-Allee 2,10585 Berlin","FlexField04":"2007-12-01","FlexField05":"Frank Baumann\r"},{"FlexField01":"28","FlexField02":"Ableseung","FlexField03":"Pascalstr. 10a,10587 Berlin","FlexField04":"2007-12-01","FlexField05":"Nils Schumann\r"},{"FlexField01":"29","FlexField02":"Instandsetzung","FlexField03":"Bismaarckstr. 10,10583 Berlin","FlexField04":"2007-12-01","FlexField05":"Uli Hoene"},{"FlexField01":"16","FlexField02":"Instandsetzung","FlexField03":"Bismaarckstr. 5,10583 Berlin","FlexField04":"2007-12-01","FlexField05":"Paule Beinlich\r"},{"FlexField01":"15","FlexField02":"Ableseung","FlexField03":"Pascalstr. 6,10587 Berlin","FlexField04":"2007-12-01","FlexField05":"Marco Rehmer\r"},{"FlexField01":"3","FlexField02":"Ableseung","FlexField03":"Pascalstr. 2,10587 Berlin","FlexField04":"2007-12-01","FlexField05":"Helmut Schmidt\r"},{"FlexField01":"5","FlexField02":"Ausschaltung","FlexField03":"Ernst-Reuter-Platz 1,10589 Ber","FlexField04":"2007-12-01","FlexField05":"Arnold Schwarzenegger\r"},{"FlexField01":"30","FlexField02":"Ableseung","FlexField03":"Pascalstr. 10b,10587 Berlin","FlexField04":"2007-12-01","FlexField05":"Dieter Hoene"},{"FlexField01":"14","FlexField02":"Ausschaltung","FlexField03":"Ernst-Reuter-Platz 4,10589 Ber","FlexField04":"2007-12-01","FlexField05":"Tim Wiese\r"},{"FlexField01":"13","FlexField02":"Ableseung","FlexField03":"Pascalstr. 5,10587 Berlin","FlexField04":"2007-12-01","FlexField05":"Oliver Kahn\r"},{"FlexField01":"2","FlexField02":"Instandsetzung","FlexField03":"Bismaarckstr. 1,10583 Berlin","FlexField04":"2007-12-02","FlexField05":"Gerd Schr"},{"FlexField01":"4","FlexField02":"Instandsetzung","FlexField03":"Bismaarckstr. 2,10583 Berlin","FlexField04":"2007-12-02","FlexField05":"Ralf M"},{"FlexField01":"6","FlexField02":"Ableseung","FlexField03":"Pascalstr. 3,10587 Berlin","FlexField04":"2007-12-04","FlexField05":"Kurt Russel\r"},{"FlexField01":"7","FlexField02":"Ausschaltung","FlexField03":"Ernst-Reuter-Platz 2,10589 Ber","FlexField04":"2007-12-04","FlexField05":"Angela Merkel\r"},{"FlexField01":"9","FlexField02":"Instandsetzung","FlexField03":"Bismaarckstr. 3,10583 Berlin","FlexField04":"2007-12-05","FlexField05":"Clemens Meyer\r"},{"FlexField01":"8","FlexField02":"Ableseung","FlexField03":"Pascalstr. 4,10587 Berlin","FlexField04":"2007-12-05","FlexField05":"Ralf Schmidt\r"},{"FlexField01":"10","FlexField02":"Ausschaltung","FlexField03":"Ernst-Reuter-Platz 3,10589 Ber","FlexField04":"2007-12-05","FlexField05":"Miro Klose\r"},{"FlexField01":"11","FlexField02":"Ableseung","FlexField03":"Pascalstr. 1,10587 Berlin","FlexField04":"2007-12-06","FlexField05":"Luca Toni\r"},{"FlexField01":"12","FlexField02":"Instandsetzung","FlexField03":"Bismaarckstr. 4,10583 Berlin","FlexField04":"2007-12-07","FlexField05":"Lukas Podolski\r"}],"totalCount":"30"}


Everything is fine, when I use this with datastore ds. But when I render the grid with datastore ds2, just the headlines are rendered and neither data is displayed nor an error message.

I guess that it is just a little mistake but I am still a newbie and couldn't fix it yet. So I would appreciate if somebody could help.

KGL

KGL
25 Jan 2008, 4:09 AM
Hi,

I could solve my prob by implementing the DnD-Function to my existing Grid that was loaded from database. I "just" had to add an HTML: Param to the grid with the needed DIV-Tags. The Java-function was implemented in my main page.

Best wishes

KGL

emmy mathew
7 Jul 2010, 11:04 PM
Hi Maya

I too wish to save new rows order in a Ext-JS Grid..Can you please tell me how you implemented it?