Search

Subscribe

Enter your email address to subscribe to this blog.

Recent Comments

Intro to Spring Security Core for Grails
Santosh said: Thanks much for putting up these screencasts. As the others here I'm a beginner and I've been having... [More]

Grails Spring Security Plugin - Logout postOnly setting
eriihine said: I still had some issues with this one. It seems that the href link is always generating a GET method... [More]

Intro to Spring Security Core for Grails
Dan Vega said: Just a heads up but I decided to write up a quick post on your question just in case it trips up any... [More]

Intro to Spring Security Core for Grails
eriihine said: Thanks for the clarification! [More]

Intro to Spring Security Core for Grails
Dan Vega said: First off thank you for the kind words. I plan on releasing more screencasts very soon. If you loo... [More]

Showing the details of a grid record

Last week while I was at cfunited I got a comment on an old post that went a little something like this.

You were working on an example to show how to click a row and show details. Is there anywhere I might see this example?
This should be pretty easy, lets go ahead and build this out. Before we get started lets take a look at what we are trying to accomplish here. We will have a grid on the left with our first and last name and when you click on a record it will populate on the right in our form.

The first thing we need to do is create the basic layout for our app. For this example we are going to use the art gallery database that ships with ColdFusion. Here we are creating the query and the grid. What's important to note here that even though we are not displaying all of the records they need to be included in the grid. If we did not the columns would not be stored in the underlying ext data store.

Next we will create our details area. At the end of all of this code we will use ajaxOnLoad to call a javascript method when the page loads. Basically all we are doing here is getting our grid object and adding a row click event listener to it. When we click on a row we are getting the record from the underlying ext data store. That record basically contains a record object. An easy way to see what the record is made up of is to log it to the console. Finally I just wrote a convenient method for setting the value of the input field.

So now we have our layout setup we just need to glue everything together.

You can check out a working demo by clicking here.

 
 

cfmobile application on riaforge

I decided to make the code available for the cfunited mobile application. I will probably setup svn so I can actually update some of the code but for now I just threw up a zip of what I had on my local machine. First off you will need to download Sencha Touch and then adjust the paths to Sencha in the index.html. There are a bunch of bugs still in the software that I will try and get to when I get home. The code is not the greatest but I whipped it together last second and it works. Also If you want to pass along any notes or feedback on the code I always love hearing that.

http://cfumobile.riaforge.org/

 
 

cfunited presentation: Mobile Applications

I just finished my "Developing web applications for mobile devices" presentation and it was awesome. Coming off of yesterdays presentation that didn't go as well as I hoped I was happy that I had to redeem myself this morning. First off I had the 1st slot today at 10 AM and I really happy I was able to get up in time ;)

I was really happy to see a full crowd in the room this morning. There was standing room only in the room and I was pretty happy to find out they were in the right room! Anyways, here is the presentation along with all of the demo code. Click on the menu button to download the code.

Thanks to a couple attendees I have some pictures from the presentation.

 
 

CFGrid Event Listeners

As you all know by now the grid in ColdFusion 8 is powered by the Ext framework. If you dive into the documentation you will find out that there is more that you can do with it then advertised. We have been looking at ways to customize the grid, today we will learn about event listeners. The grid has the ability to announce events as they are happening even if you are not listening for them. Events can include clicking on a row double clicking on a cell or even using a keyboard shortcut. Just knowing that the gird announces these events will do you no good, you need the ability to listen for them.

The grid gives you 2 methods to listen for events. The following methods will append an event handler to this component the on method is just shorthand for addListener.

  • addListener( String eventName, Function handler, [Object scope], [Object options] ) : void
  • on( String eventName, Function handler, [Object scope], [Object options] ) : void
These methods belong to the grid so to use them you need to have the grid object. Fortunately for you ColdFusion provides an easy way to get the grid object. If you have been following my examples than the following should look familiar. I am using the cfartgallery data source that ships with CF8 so you can follow along at home. The code below will run a query and create a grid with the name of ArtistGrid. The name is important because that is how we will get our grid object later on. Finally the last line will call the init method when the page loads.
view plain print about
1<cfquery name="getArtists" datasource="cfartgallery">
2    SELECT artistId, firstname, lastname, address, city, state, postalcode, email
3    FROM 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    <cfset args.selectOnLoad = false>
13    
14    <cfform>
15        <cfgrid attributeCollection="#args#">
16            <cfgridcolumn name="artistid" display="false">
17            <cfgridcolumn name="firstname" header="First Name">
18            <cfgridcolumn name="lastname" header="Last Name">
19            <cfgridcolumn name="email" header="Email Address">
20            <cfgridcolumn name="address" header="Address">
21            <cfgridcolumn name="city" header="City">
22            <cfgridcolumn name="state" header="State">
23            <cfgridcolumn name="postalcode" header="Zip">
24        </cfgrid>
25    </cfform>
26    
27    <cfset ajaxOnLoad("init")>

Now that our grid is setup we can setup our init method. Remember I said ColdFusion makes it easy, I was not lying, the getGridObject will get our grid for us.

view plain print about
1<script type="text/javascript">
2 function init(){
3 //get the grid component
4 grid = ColdFusion.Grid.getGridObject("ArtistGrid");
5 </script>
Now that we have our grid object we can start adding listeners. Lets say we wanted to call a method when a row is clicked. Here we are listening to for a row to be clicked and then calling a method named editArtist. Our editArtist method also get some information about the row being clicked. So How did i know what information would be passed?
view plain print about
1<script type="text/javascript">
2 function init(){
3     //get the grid component
4        grid = ColdFusion.Grid.getGridObject("ArtistGrid");
5        
6        //Fires when a row is clicked
7        grid.addListener("rowclick",editArtist);
8        
9 }
10
11 function editArtist(grid,rowIndex,e){
12     var record = grid.getDataSource().getAt(rowIndex);
13     console.log(record);
14 }
15
16 </script>
If we look at the documentation for the grid event listeners we will get some more details about them. The arguments are what will get passed to use when that event is fired.
  • bodyscroll : ( Number scrollLeft, Number scrollTop ) - Fires when the body element is scrolled
  • cellclick : ( Grid this, Number rowIndex, Number columnIndex, Ext.EventObject e ) - Fires when a cell is clicked
  • cellcontextmenu : ( Grid this, Number rowIndex, Number cellIndex, Ext.EventObject e ) - Fires when a cell is right clicked
  • celldblclick : ( Grid this, Number rowIndex, Number columnIndex, Ext.EventObject e ) - Fires when a cell is double clicked
  • click : ( Ext.EventObject e ) - The raw click event for the entire grid.
  • columnmove : ( Number oldIndex, Number newIndex ) - Fires when the user moves a column
  • columnresize : ( Number columnIndex, Number newSize ) - Fires when the user resizes a column
  • contextmenu : ( Ext.EventObject e )The raw contextmenu event for the entire grid.
  • dblclick : ( Ext.EventObject e ) - The raw dblclick event for the entire grid.
  • dragdrop : ( Grid this, Ext.GridDD dd, String targetId, event e ) - Fires when dragged row(s) are dropped on a valid DD target
  • dragenter : ( Grid this, Ext.GridDD dd, String targetId, event e ) - Fires when the dragged row(s) first cross another DD target while being dragged
  • dragout : ( Grid this, Ext.GridDD dd, String targetId, event e ) - Fires when the dragged row(s) leave another DD target while being dragged
  • dragover : ( Grid this, Ext.GridDD dd, String targetId, event e ) - Fires while row(s) are being dragged. "targetId" is the id of the Yahoo.util.DD object the selected rows are being dr...
  • enddrag : ( Grid this, Ext.GridDD dd, event e ) - Fires when a drag operation is complete
  • headerclick : ( Grid this, Number columnIndex, Ext.EventObject e ) - Fires when a header is clicked
  • headercontextmenu : ( Grid this, Number columnIndex, Ext.EventObject e ) - Fires when a header is right clicked
  • headerdblclick : ( Grid this, Number columnIndex, Ext.EventObject e ) - Fires when a header cell is double clicked
  • keydown : ( Ext.EventObject e ) - The raw keydown event for the entire grid.
  • keypress : ( Ext.EventObject e ) - The raw keypress event for the entire grid.
  • mousedown : ( Ext.EventObject e ) - The raw mousedown event for the entire grid.
  • mouseout : ( Ext.EventObject e ) - The raw mouseout event for the entire grid.
  • mouseover : ( Ext.EventObject e ) - The raw mouseover event for the entire grid.
  • mouseup : ( Ext.EventObject e ) - The raw mouseup event for the entire grid.
  • render : ( Grid grid ) - Fires when the grid is rendered
  • rowclick : ( Grid this, Number rowIndex, Ext.EventObject e ) - Fires when a row is clicked
  • rowcontextmenu : ( Grid this, Number rowIndex, Ext.EventObject e ) - Fires when a row is right clicked
  • rowdblclick : ( Grid this, Number rowIndex, Ext.EventObject e ) - Fires when a row is double clicked
  • startdrag : ( Grid this, Ext.GridDD dd, event e ) - Fires when row(s) start being dragged
And that is how we are able to find out more information about the event that is happening. In our editArtist method we are getting passed the rowIndex, this allows us to look up what record what clicked. As you can see event listeners can be very powerful and just another way that you can customize your grid components. Please feel free to leave me any questions you might have about them.

 
 

Custom Grid Editor

Earlier today I wrote a short tutorial on grid editing. The tutorial walked you through on how you could easily edit your data right in a grid. While this is great it really is limited to certain use cases and on top of that we are limited with what the user can chose. In our example before we had a bunch of data including the state the artist lives in. If this were a full edit screen we would allow them to select a state from a drop down but in our grid it simply provides them a text box. What if there were a way to customize the editors for each field? Well there is and it really is not that hard. This tutorial will show you a state drop down box and hopefully Ill show you some more in the near future.

Like most of my grid tutorials we are going to use the cfartgallery data source that ships with ColdFusion 8. The first thing we are going to do is create our grid, make it editable and call a function named init after the page loads. If you have been following my grid tutorials this should look famailiar.

view plain print about
1<cfquery name="getArtists" datasource="cfartgallery">
2 SELECT artistId, firstname, lastname, address, city, state, postalcode, email
3 FROM Artists
4 </cfquery>
5
6 <cfset args = structNew()>
7 <cfset args.name = "ArtistGrid">
8    <cfset args.width = 600>
9 <cfset args.format = "html">
10 <cfset args.query = "getArtists">
11 <cfset args.stripeRows = true>
12 <cfset args.selectColor = "##D9E8FB">
13 <cfset args.selectmode = "edit">
14 <cfset args.onchange = "cfc:artists.editArtist({cfgridaction},{cfgridrow},{cfgridchanged})">
15
16 <cfform>
17 <cfgrid attributeCollection="#args#">
18 <cfgridcolumn name="artistid" display="false">
19 <cfgridcolumn name="firstname" header="First Name">
20 <cfgridcolumn name="lastname" header="Last Name">
21 <cfgridcolumn name="address" header="Address">
22 <cfgridcolumn name="city" header="City">
23 <cfgridcolumn name="state" header="State">
24 <cfgridcolumn name="postalcode" header="Zip">
25 </cfgrid>
26 </cfform>
27
28 <cfset ajaxOnLoad("init")>
Now comes the real magic. First we need to get our grid object using the built in ColdFusion method getGridObject(). Next we need the column model and finally using the column model we can find out the index of our state column. The reason we need the index number will become clear in a second.
view plain print about
1//grid object
2 grid = ColdFusion.Grid.getGridObject("ArtistGrid");
3 //column model
4 cm = grid.getColumnModel();
5 //we need to know the column id
6 stIndex = cm.findColumnIndex("STATE");
I am now going to create a combo box which will contain a list of all the states. Right now this will not show up or really do anything.
view plain print about
1cb = new Ext.form.ComboBox({
2 id:"state",
3 mode:"local",
4 triggerAction:"all",
5 displayField:"text",
6 valueField:"value",
7 store:new Ext.data.SimpleStore({
8 fields: ["value", "text"],
9 data: [
10 ['AL', 'Alabama'],
11 ['AK', 'Alaska'],
12 ['AZ', 'Arizona'],
13 ['AR', 'Arkansas'],
14 ['CA', 'California'],
15 ['CO', 'Colorado'],
16 ['CT', 'Connecticut'],
17 ['DE', 'Delaware'],
18 ['DC', 'District of Columbia'],
19 ['FL', 'Florida'],
20 ['GA', 'Georgia'],
21 ['HI', 'Hawaii'],
22 ['ID', 'Idaho'],
23 ['IL', 'Illinois'],
24 ['IN', 'Indiana'],
25 ['IA', 'Iowa'],
26 ['KS', 'Kansas'],
27 ['KY', 'Kentucky'],
28 ['LA', 'Louisiana'],
29 ['ME', 'Maine'],
30 ['MD', 'Maryland'],
31 ['MA', 'Massachusetts'],
32 ['MI', 'Michigan'],
33 ['MN', 'Minnesota'],
34 ['MS', 'Mississippi'],
35 ['MO', 'Missouri'],
36 ['MT', 'Montana'],
37 ['NE', 'Nebraska'],
38 ['NV', 'Nevada'],
39 ['NH', 'New Hampshire'],
40 ['NJ', 'New Jersey'],
41 ['NM', 'New Mexico'],
42 ['NY', 'New York'],
43 ['NC', 'North Carolina'],
44 ['ND', 'North Dakota'],
45 ['OH', 'Ohio'],
46 ['OK', 'Oklahoma'],
47 ['OR', 'Oregon'],
48 ['PA', 'Pennsylvania'],
49 ['RI', 'Rhode Island'],
50 ['SC', 'South Carolina'],
51 ['SD', 'South Dakota'],
52 ['TN', 'Tennessee'],
53 ['TX', 'Texas'],
54 ['UT', 'Utah'],
55 ['VT', 'Vermont'],
56 ['VA', 'Virginia'],
57 ['WA', 'Washington'],
58 ['WV', 'West Virginia'],
59 ['WI', 'Wisconsin'],
60 ['WY', 'Wyoming']
61 ]
62 })
63 });
Finally each column has a defined editor. At the time the grid is built it is usually a text field or number field. To change the editor we need to set a new editor using the column models set editor method. This method takes 2 arguments, the index of the column (we got this earlier) and the new editor. The grid editor takes a form field definition. We are simply adding our combo box but this could easily be a date picker, color picker or custom editor.
view plain print about
1cm.setEditor(stIndex,new Ext.grid.GridEditor(cb));

For those of you just joining me I am not running 8 so I can't show you a live demo but here are some images. When you double click the cell the combo box appears with the correct value selected. Then you can choose a state and when the combo box changes a new value is selected a red marker will appear noting that the value has changed.



Here is a the final code used for the example. As always please feel free to leave your questions or comments.
view plain print about
1<cfsetting showdebugoutput="false">
2<html>
3<head>
4 <title>Edit Artist Grid</title>
5 <script type="text/javascript">
6 function init(){
7 //grid object
8 grid = ColdFusion.Grid.getGridObject("ArtistGrid");
9 //column model
10 cm = grid.getColumnModel();
11 //we need to know the column id
12 stIndex = cm.findColumnIndex("STATE");
13
14 cb = new Ext.form.ComboBox({
15 id:"state",
16 mode:"local",
17 triggerAction:"all",
18 displayField:"text",
19 valueField:"value",
20 store:new Ext.data.SimpleStore({
21 fields: ["value", "text"],
22 data: [
23 ['AL', 'Alabama'],
24 ['AK', 'Alaska'],
25 ['AZ', 'Arizona'],
26 ['AR', 'Arkansas'],
27 ['CA', 'California'],
28 ['CO', 'Colorado'],
29 ['CT', 'Connecticut'],
30 ['DE', 'Delaware'],
31 ['DC', 'District of Columbia'],
32 ['FL', 'Florida'],
33 ['GA', 'Georgia'],
34 ['HI', 'Hawaii'],
35 ['ID', 'Idaho'],
36 ['IL', 'Illinois'],
37 ['IN', 'Indiana'],
38 ['IA', 'Iowa'],
39 ['KS', 'Kansas'],
40 ['KY', 'Kentucky'],
41 ['LA', 'Louisiana'],
42 ['ME', 'Maine'],
43 ['MD', 'Maryland'],
44 ['MA', 'Massachusetts'],
45 ['MI', 'Michigan'],
46 ['MN', 'Minnesota'],
47 ['MS', 'Mississippi'],
48 ['MO', 'Missouri'],
49 ['MT', 'Montana'],
50 ['NE', 'Nebraska'],
51 ['NV', 'Nevada'],
52 ['NH', 'New Hampshire'],
53 ['NJ', 'New Jersey'],
54 ['NM', 'New Mexico'],
55 ['NY', 'New York'],
56 ['NC', 'North Carolina'],
57 ['ND', 'North Dakota'],
58 ['OH', 'Ohio'],
59 ['OK', 'Oklahoma'],
60 ['OR', 'Oregon'],
61 ['PA', 'Pennsylvania'],
62 ['RI', 'Rhode Island'],
63 ['SC', 'South Carolina'],
64 ['SD', 'South Dakota'],
65 ['TN', 'Tennessee'],
66 ['TX', 'Texas'],
67 ['UT', 'Utah'],
68 ['VT', 'Vermont'],
69 ['VA', 'Virginia'],
70 ['WA', 'Washington'],
71 ['WV', 'West Virginia'],
72 ['WI', 'Wisconsin'],
73 ['WY', 'Wyoming']
74 ]
75 })
76 });
77
78 cm.setEditor(stIndex,new Ext.grid.GridEditor(cb));
79
80 }
81 </script>
82</head>
83
84<body>
85
86 <link href="/CFIDE/scripts/ajax/ext/resources/css/ytheme-aero.css" rel="stylesheet" type="text/css">
87
88 <cfquery name="getArtists" datasource="cfartgallery">
89 SELECT artistId, firstname, lastname, address, city, state, postalcode, email
90 FROM Artists
91 </cfquery>
92
93 <cfset args = structNew()>
94 <cfset args.name = "ArtistGrid">
95    <cfset args.width = 600>
96 <cfset args.format = "html">
97 <cfset args.query = "getArtists">
98 <cfset args.stripeRows = true>
99 <cfset args.selectColor = "##D9E8FB">
100 <cfset args.selectmode = "edit">
101 <cfset args.onchange = "cfc:artists.editArtist({cfgridaction},{cfgridrow},{cfgridchanged})">
102
103 <cfform>
104 <cfgrid attributeCollection="#args#">
105 <cfgridcolumn name="artistid" display="false">
106 <cfgridcolumn name="firstname" header="First Name">
107 <cfgridcolumn name="lastname" header="Last Name">
108 <cfgridcolumn name="address" header="Address">
109 <cfgridcolumn name="city" header="City">
110 <cfgridcolumn name="state" header="State">
111 <cfgridcolumn name="postalcode" header="Zip">
112 </cfgrid>
113 </cfform>
114
115 <cfset ajaxOnLoad("init")>
116</body>
117</html>
 
 

More Entries