ColdFusion 8 has some great AJAX features built in as we all know. One of the more popular tags is the cfgrid in HTML format. This grid as we know really just wraps the Ext 1.1 framework. One question I see often is how can add some context menus to my grid. This would be both when you click on a row in the grid and on the grids header. This tutorial should clear up some of the questions everyone has been asking. First off I need to say this is not perfect. I do tons of Ext 2.0 work and it works great in 2.0 but there is a minor problem and I am sure after this post someone will point out a fix.
Ok, first thing we need to do is create a basic grid for us to use. I am going to use the cfartgallery datasource that is shipped with ColdFusion 8. Basically we just query our database, create an attribute structure (you don't have to do this I just like it this way) and output our grid. If your not sure about the grid code It is pretty basic, just read up on it.
ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org
<cfquery name="getArtists" datasource="cfartgallery">
SELECT artistId, firstname, lastname, address, city, state, postalcode, email
FROM Artists
</cfquery>
<cfset args = structNew()>
<cfset args.name = "ArtistGrid">
<cfset args.format = "html">
<cfset args.query = "getArtists">
<cfset args.stripeRows = true>
<cfset args.selectColor = "##D9E8FB">
<cfform>
<cfgrid attributeCollection="#args#">
<cfgridcolumn name="artistid" display="false">
<cfgridcolumn name="firstname" header="First Name">
<cfgridcolumn name="lastname" header="Last Name">
<cfgridcolumn name="email" header="Email Address">
<cfgridcolumn name="address" header="Address">
<cfgridcolumn name="city" header="City">
<cfgridcolumn name="state" header="State">
<cfgridcolumn name="postalcode" header="Zip">
</cfgrid>
</cfform>
1<cfquery name="getArtists" datasource="cfartgallery">
2SELECT artistId, firstname, lastname, address, city, state, postalcode, email
3FROM Artists
4</cfquery>
5
6<cfset args = structNew()>
7<cfset args.name = "ArtistGrid">
8<cfset args.format = "html">
9<cfset args.query = "getArtists">
10<cfset args.stripeRows = true>
11<cfset args.selectColor = "##D9E8FB">
12
13<cfform>
14 <cfgrid attributeCollection="#args#">
15 <cfgridcolumn name="artistid" display="false">
16 <cfgridcolumn name="firstname" header="First Name">
17 <cfgridcolumn name="lastname" header="Last Name">
18 <cfgridcolumn name="email" header="Email Address">
19 <cfgridcolumn name="address" header="Address">
20 <cfgridcolumn name="city" header="City">
21 <cfgridcolumn name="state" header="State">
22 <cfgridcolumn name="postalcode" header="Zip">
23 </cfgrid>
24</cfform>
Now that we have our grid we need to do a couple things. First we need to call a JavaScript function after our grid loads. To do this I can simply use the ajaxOnLoad tag. This will tell us to call the init method when the page loads. We will get to this function in a second.
ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org
<cfset ajaxOnLoad("init")>
1<cfset ajaxOnLoad("init")>
The next thing we need to do is include the necessary files to create menus in Ext. A context menu or right click menu is nothing more than a basic menu in Ext. The reason we need to do this is because this page does not use the menu files only a grid so we need to manually include them. I have also chosen to import the aero theme and the menu stylesheets.
ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org
<script type="text/javascript" src="/CFIDE/scripts/ajax/ext/package/menu/menus.js"></script>
<link href="/CFIDE/scripts/ajax/ext/resources/css/ytheme-aero.css" rel="stylesheet" type="text/css">
<link href="/CFIDE/scripts/ajax/ext/resources/css/menu.css" type="text/css" rel="stylesheet"/>
1<script type="text/javascript" src="/CFIDE/scripts/ajax/ext/package/menu/menus.js"></script>
2 <link href="/CFIDE/scripts/ajax/ext/resources/css/ytheme-aero.css" rel="stylesheet" type="text/css">
3 <link href="/CFIDE/scripts/ajax/ext/resources/css/menu.css" type="text/css" rel="stylesheet"/>
Now for the real magic. Once the grid is created we can add event listeners to the grid. The way we do that is by getting the grid object and calling its addListener method. One of the listeners the Ext framework exposes is the rowcontextmenu listener. This will tell our grid to to listen for context menus. Here we are just using an anonymous function that gets passed the grid object, the row that was click and the event that caused the context menu.
ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org
<script type="text/javascript">
function init(){
grid = ColdFusion.Grid.getGridObject("ArtistGrid");
grid.addListener("rowcontextmenu", function(grid, rowIndex, e) {
var record = grid.getDataSource().getAt(rowIndex); // Get the Record
});
}
</script>
1<script type="text/javascript">
2 function init(){
3 grid = ColdFusion.Grid.getGridObject("ArtistGrid");
4
5 grid.addListener("rowcontextmenu", function(grid, rowIndex, e) {
6 var record = grid.getDataSource().getAt(rowIndex); // Get the Record
7
8 });
9
10 }
11 </script>
Now we need to create our menu. I am just creating 2 basic menu items that have a click handler. When the menu item is clicked the onClick method is called. In the full source you will see this method just displays an alert box. Next we need to stope the browser for showing its default context menu. We do that by using the stopEvent method passed by our Event Object. Finally where do we show this menu, well we can capture where the user right clicked.
ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org
var contextMenu = new Ext.menu.Menu();
contextMenu.add({text:"Edit Record",handler:onClick});
contextMenu.add({text:"View Record",handler:onClick});
// Stops the browser context menu from showing.
e.stopEvent();
// show menu at
contextMenu.showAt(e.xy);
1var contextMenu = new Ext.menu.Menu();
2 contextMenu.add({text:"Edit Record",handler:onClick});
3 contextMenu.add({text:"View Record",handler:onClick});
4
5 // Stops the browser context menu from showing.
6 e.stopEvent();
7 // show menu at
8 contextMenu.showAt(e.xy);
And that is all there is to it. Also, now the removed the browsers context menu we have the ability to right click on the the grids header and display those fancy menus. Now remember I told you it was not perfect. There seems to be a couple of CSS issues but nothing major and something I am sure someone will fix. I have some screen shots below and the full source for the example. Please feel free to drop me a question.
Full Example Code
ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org
<html>
<head>
<title>Basic Grid Example</title>
<script type="text/javascript" src="/CFIDE/scripts/ajax/ext/package/menu/menus.js"></script>
<script type="text/javascript">
function init(){
grid = ColdFusion.Grid.getGridObject("ArtistGrid");
grid.addListener("rowcontextmenu", function(grid, rowIndex, e) {
var record = grid.getDataSource().getAt(rowIndex); // Get the Record
var contextMenu = new Ext.menu.Menu();
contextMenu.add({text:"Edit Record",handler:onClick});
contextMenu.add({text:"View Record",handler:onClick});
// Stops the browser context menu from showing.
e.stopEvent();
// show menu at
contextMenu.showAt(e.xy);
});
}
function onClick(){
alert("hello")
}
</script>
</head>
<body>
<cfquery name="getArtists" datasource="cfartgallery">
SELECT artistId, firstname, lastname, address, city, state, postalcode, email
FROM Artists
</cfquery>
<cfset args = structNew()>
<cfset args.name = "ArtistGrid">
<cfset args.format = "html">
<cfset args.query = "getArtists">
<cfset args.stripeRows = true>
<cfset args.selectColor = "##D9E8FB">
<cfform>
<cfgrid attributeCollection="#args#">
<cfgridcolumn name="artistid" display="false">
<cfgridcolumn name="firstname" header="First Name">
<cfgridcolumn name="lastname" header="Last Name">
<cfgridcolumn name="email" header="Email Address">
<cfgridcolumn name="address" header="Address">
<cfgridcolumn name="city" header="City">
<cfgridcolumn name="state" header="State">
<cfgridcolumn name="postalcode" header="Zip">
</cfgrid>
</cfform>
<cfset ajaxOnLoad("init")>
<cfsavecontent variable="head">
<link href="/CFIDE/scripts/ajax/ext/resources/css/ytheme-aero.css" rel="stylesheet" type="text/css">
<link href="/CFIDE/scripts/ajax/ext/resources/css/menu.css" type="text/css" rel="stylesheet"/>
</cfsavecontent>
<cfhtmlhead text="#head#">
</body>
</html>
1<html>
2<head>
3 <title>Basic Grid Example</title>
4
5 <script type="text/javascript" src="/CFIDE/scripts/ajax/ext/package/menu/menus.js"></script>
6
7 <script type="text/javascript">
8 function init(){
9 grid = ColdFusion.Grid.getGridObject("ArtistGrid");
10
11 grid.addListener("rowcontextmenu", function(grid, rowIndex, e) {
12 var record = grid.getDataSource().getAt(rowIndex); // Get the Record
13
14 var contextMenu = new Ext.menu.Menu();
15 contextMenu.add({text:"Edit Record",handler:onClick});
16 contextMenu.add({text:"View Record",handler:onClick});
17
18 // Stops the browser context menu from showing.
19 e.stopEvent();
20 // show menu at
21 contextMenu.showAt(e.xy);
22
23 });
24
25 }
26 function onClick(){
27 alert("hello")
28 }
29 </script>
30</head>
31<body>
32
33 <cfquery name="getArtists" datasource="cfartgallery">
34 SELECT artistId, firstname, lastname, address, city, state, postalcode, email
35 FROM Artists
36 </cfquery>
37
38 <cfset args = structNew()>
39 <cfset args.name = "ArtistGrid">
40 <cfset args.format = "html">
41 <cfset args.query = "getArtists">
42 <cfset args.stripeRows = true>
43 <cfset args.selectColor = "##D9E8FB">
44
45 <cfform>
46 <cfgrid attributeCollection="#args#">
47 <cfgridcolumn name="artistid" display="false">
48 <cfgridcolumn name="firstname" header="First Name">
49 <cfgridcolumn name="lastname" header="Last Name">
50 <cfgridcolumn name="email" header="Email Address">
51 <cfgridcolumn name="address" header="Address">
52 <cfgridcolumn name="city" header="City">
53 <cfgridcolumn name="state" header="State">
54 <cfgridcolumn name="postalcode" header="Zip">
55 </cfgrid>
56 </cfform>
57
58 <cfset ajaxOnLoad("init")>
59
60
61
62 <cfsavecontent variable="head">
63 <link href="/CFIDE/scripts/ajax/ext/resources/css/ytheme-aero.css" rel="stylesheet" type="text/css">
64 <link href="/CFIDE/scripts/ajax/ext/resources/css/menu.css" type="text/css" rel="stylesheet"/>
65 </cfsavecontent>
66
67 <cfhtmlhead text="#head#">
68
69</body>
70</html>
This entry was posted on March 4, 2008 at 11:11 PM and has received 11005 views. Comments 20 |
Print this entry.
#1 by Henry on 3/5/08 - 2:37 PM
Question: how do u hide CFGRIDROWINDEX in header context menu -> Columns ? Without the ability to hide that, it is just not acceptable to use that feature as site user might find that confusing, especially when selectmode="edit"
#2 by Steve 'Cutter' Blades on 3/5/08 - 4:25 PM
#3 by Jared Shields on 3/5/08 - 10:16 PM
#4 by xavier on 4/7/08 - 2:03 AM
grid.addListener("afteredit", function(e){
ColdFusion.navigate('stats.cfm', 'statsDiv');
});
Looks like the afteredit is fired after the grid edit but before the database update happens and hence I don't get the status after the database update. Any idea how this can be done?
#5 by Gary Habermann on 4/17/08 - 1:18 PM
#6 by Dan Vega on 4/17/08 - 1:20 PM
#7 by Gary Habermann on 4/17/08 - 2:35 PM
Server Product ColdFusion
Version 8,0,0,176276
Edition Enterprise
When I click on the row the follow message appears in the CFDEBUG window:
info: widget: Firing selection change event for grid id: UserDocGrid
I am getting fire bug now.
Thanks
Gary
#8 by Chad Ramey on 4/30/08 - 11:18 AM
#9 by Dana on 5/1/08 - 9:38 AM
info:widget: Firing selection change event for grid id: ArtistGrid
Could someone please help. I am not using the c drive, I am using a different drive letter, I didnt know if that made a difference.
#10 by Chad Ramey on 5/1/08 - 9:40 AM
// Stops the browser context menu from showing. e.stopEvent();
// show menu at contextMenu.showAt(e.xy);
should be like this.
// Stops the browser context menu from showing.
e.stopEvent();
// show menu at
contextMenu.showAt(e.xy);
#11 by Dan Vega on 5/1/08 - 9:42 AM
#12 by Chad Ramey on 5/1/08 - 9:43 AM
Has any one experienced any issues with the context menus showing the list-style circle?
Add this to the <head> of your page.
<style>
.x-menu-list{
margin: 0px; padding: 0px; list-style: none; background: none !important;
}
</style>
#13 by Dan Vega on 5/1/08 - 9:46 AM
#14 by Chad Ramey on 5/1/08 - 9:47 AM
#15 by Dana on 5/1/08 - 10:50 AM
Chad, I completely over looked that.
#16 by Scott on 10/20/08 - 10:46 AM
#17 by Henry Ho on 10/20/08 - 1:15 PM
#18 by Scott on 10/27/08 - 9:10 AM
#19 by Bud Hines on 10/29/08 - 9:18 PM
var contextMenu = new Ext.menu.Menu();
contextMenu.add({text:"Edit Record",handler:onClick});
contextMenu.add({text:"View Record",handler:onClick});
Is there a library I need to include?
thanks,
Bud
#20 by JertoZ on 12/10/09 - 11:39 AM
http://ccinct.com/lab/filter-grid/
The website provide source code for php. I have searched through the forums but I haven't found an equivalent written for coldfusion/js.
It would be great if someone could help me with that.
Thanks