PDA

View Full Version : Example Request for A Grid-Dialog Combination



Bobafart
2 May 2007, 6:50 AM
I have made a grid with the following structure:

id(not shown) | Soldier Name | Soldier Specialty
3 | Joe | Sniper
7 | Mack | Heavy Weapons

The first column is not actually shown, it is hidden data.

I am trying to make a modal dialog that appears when the user clicks on a row in the grid -- the modal dialog will have data loaded using the id of the row clicked to load in the dialog.

Does anyone have a working example of a grid that loads data into a dialog when the row is clicked that I can learn from?

TopKatz
2 May 2007, 7:04 AM
I have an example, but its 500 lines of code, so Ill try and jsut show you wah tyou need to add to existing examples.

Obviously you need a grid, and a dialog, then:

attach a listner to your grid for the row click:


grid.addListener("rowclick", rowClicked, this);

Then you need a function to handle it:


function rowClicked(grid, rowClicked, e) {
var selectionModel = grid.getSelectionModel();
var record = selectionModel.getSelected();

var msgNum = record.data['noteID'];
var msgText = record.data['noteText'];
var msgFrom = record.data['fromUserID'];
var msgFromID = record.data['fromID'];
var msgDate = record.data['noteDate'];
var msgSubject = record.data['noteSubject'];

viewMessage.showDialog(msgText, msgFrom, msgNum, msgFromID, msgDate, msgSubject)


so grid is a reference to my grid object, I then attach the function rowClicked to "rowclick" event. Then I grab all the data I want from the grid to pass to my dialog viewMessage (you could async this if you want, but I had the data on the client side, so I just pass it along!). My showDialog method in the viewMessage function is looking for all of those variables to be passed along. Then I use them to build my data.

Hope that helps....

Bobafart
2 May 2007, 7:39 AM
Hi TopKatz,

thanks for your help.

I am trying to get the database ID of the row that was clicked, not the number of the row clicked.

So, using my above example if soldier "Joe" is ID = 3 in my database I need to do an async request in my dialog to output the data for ID = 3.

The number of the row clicked in the grid is irrelevant in my application since the number of the row clicked can be different than the database ID.

So, to solve my problem I thought I would "hide" the database ID for each soldier row in the grid. Hence:


var cm = new Ext.grid.ColumnModel([
{header: "SoldierID", isHidden: true, dataIndex: 'troopID'},


What I am trying to do now is have an addListener that takes the SoldierID when the row is clicked and uses this ID for the async request to output more data about the particular row clicked in the dialog.

Do you know how I would do this?

TopKatz
2 May 2007, 7:45 AM
My example alows you to access all the data that is mapped to that row. As long as you sent it to the grid, you can access it in the rowClick function. So in the rowClicked function:


var id = record.data['id'];

Would give you your id number.

Any data you sent over, you have access to, you just need to use record.data['yourDataMap'];.

Edit: did not see your data map, so it will look like this

var dbID = record.data['troopID'];

BTW, I do not show my noteID either, infact its not even hidden. Its just in my datastore!

Bobafart
2 May 2007, 7:49 AM
gotcha. thanks! much appreciated.

using your advice now.

Bobafart
2 May 2007, 8:01 AM
Hmm weird.. I keep getting this error:



Error: selectionModel.getSelected is not a function


I am looking for getSelected in the docs and I can't seem to find it either. I wish there was a search function for the docs.

I create my grid (which works fine by the way):



var grid = new Ext.grid.EditorGrid('myGrid', {
ds: ds,
cm: cm
});


and then I add my Listener:



grid.addListener('cellclick',
function (grid, rowIndex, colIndex, e) {
var selectionModel = grid.getSelectionModel();
var record = selectionModel.getSelected();
var boo = record.data['Soldier'];
alert(boo);

...


keep getting the getSelected not a function error.

TopKatz
2 May 2007, 8:11 AM
probably because grid is not rendered yet? My example was some what sparse. I add the listner, then grid.render() , then do my datastore load, after that I declare my rowClicked() function, so the grid exists. In your code your doing it all at the same time before you render teh grid, which might explain why the selection model does not exist yet.

Just a thought......

Bobafart
2 May 2007, 9:13 AM
Bummer. I put it in the same order as you and it still outputs the same error.


Hmm..

TopKatz
2 May 2007, 9:19 AM
post your code now please.....

TopKatz
2 May 2007, 9:30 AM
can your rowClicked function see your grid object?

In my code the grid and the rowClicked() function are both in the same function, so grid can be reached by that function. If I have to dpaste my code I will.... its just large and complex, and probably will confuse more then help

Bobafart
2 May 2007, 10:10 AM
The below code loads fine with no errors.

The selectionModel.getSelected is not a function error occurs only when the cell is clicked (and the addListener is activated):



<script type="text/javascript">

Ext.onReady(function(){

// create the Data Store
var ds = new Ext.data.Store({
// load using HTTP
proxy: new Ext.data.HttpProxy({url: 'php/armyExt.php'}),

// the return will be XML, so lets set up a reader
reader: new Ext.data.XmlReader({
// records will have an "Item" tag
record: 'item',
id: 'troopId'
}, [
// set up the fields mapping into the xml doc
// The first needs mapping, the others are very basic
{name: 'troopName', mapping: 'itemAttribute > troopName'},
'troopHP', 'troopSquad', 'troopSpecialty', 'troopRank'
])
});

var cm = new Ext.grid.ColumnModel([
{header: "SoldierID", isHidden: true, dataIndex: 'troopId'},
{header: "Soldier", width: 120, dataIndex: 'troopName'},
{header: "HP", width: 100, dataIndex: 'troopHP'},
{header: "Squad",
width: 100,
dataIndex: 'troopSquad',
editor: new Ext.grid.GridEditor(new Ext.form.ComboBox({
typeAhead: true,
editable: false,
triggerAction: 'all',
transform:'troopSquad',
lazyRender:true
}))
},
{header: "Specialty", width: 100, dataIndex: 'troopSpecialty'},
{header: "Rank", width: 100, dataIndex: 'troopRank'}
]);
cm.defaultSortable = true;

// create the grid
var grid = new Ext.grid.EditorGrid('armyGrid', {
ds: ds,
cm: cm
});
grid.render();
ds.load();

// define the dialog variable
var dialog;
grid.addListener('cellclick',
function (grid, rowIndex, colIndex, e) {
var selectionModel = grid.getSelectionModel();
var record = selectionModel.getSelected();
var boo = record.data['Soldier'];
alert(boo);
if(colIndex==4){
if(!dialog){ // lazy initialize the dialog and only create it once
dialog = new Ext.LayoutDialog("soldierDetails", {
modal:true,
width:600,
height:400,
shadow:true,
minWidth:300,
minHeight:300,
proxyDrag: true,
west: {
split:true,
initialSize: 150,
minSize: 100,
maxSize: 250,
titlebar: true,
collapsible: true,
animate: true
},
center: {
autoScroll:true,
tabPosition: 'top',
closeOnTab: true,
alwaysShowTabs: true
}
});
dialog.addKeyListener(27, dialog.hide, dialog);
dialog.addButton('Submit', dialog.hide, dialog);
dialog.addButton('Close', dialog.hide, dialog);

var layout = dialog.getLayout();
layout.beginUpdate();
layout.add('west', new Ext.ContentPanel('west', {title: 'Inventory'}));
layout.add('center', new Ext.ContentPanel('center', {title: 'Unit Profile'}));
// generate some other tabs
layout.add('center', new Ext.ContentPanel('statistics', {
autoCreate:true, title: 'Unit Statistics', background:true}));
layout.add('center', new Ext.ContentPanel('skills', {
autoCreate:true, title: 'Unit Skills', closable:true, background:true}));
layout.endUpdate();
}
dialog.show();
}
});
});

TopKatz
2 May 2007, 10:21 AM
you need to add the listner in the grid code, not the dialog, and it needs to hapen before you render it:


grid.addListener("rowclick", rowClicked, this);
grid.render();
ds.load();

right now you are adding the listner after the grid is built, in your dialog.

This is wrong:


var dialog;
grid.addListener('cellclick',
function (grid, rowIndex, colIndex, e) {
var selectionModel = grid.getSelectionModel();
var record = selectionModel.getSelected();
var boo = record.data['Soldier'];
alert(boo);
if(colIndex==4){

Bobafart
2 May 2007, 10:26 AM
[QUOTE=TopKatz;27595]you need to add the listner in the grid code, not the dialog, and it needs to hapen before you render it:


grid.addListener("rowclick", rowClicked, this);
grid.render();
ds.load();

For the record, it makes no difference if I render the grid before or after my listener.

I tried it both ways and I get the same error. Makes no difference.

TopKatz
2 May 2007, 10:34 AM
OK, here is my message system. Its two dialogs and a grid. The layout dialog holds the grid(which is built in the init), the second dialog gets called from the rowClick of the grid.

http://dpaste.com/9486/

TopKatz
2 May 2007, 10:45 AM
I see the problem, Im sorry ...

you need :

selModel: new Ext.grid.RowSelectionModel({singleSelect:true}),

in your grid config


grid = new Ext.grid.Grid('msg-message', {
ds: msgDataStore,
cm: cm,
selModel: new Ext.grid.RowSelectionModel({singleSelect:true}),
enableColLock:false,
loadMask: true

});

Line 92 in my dpaste