CFDirectory Multiple Filters

Word Count: 285

This morning I was reading an entry by Ben Nadel on using single character wild cards. The article was a good one and I learned something new but I also posted comment saying how it would be great if we could use multiple filters. Steve Withington posted a response showing that indeed you could do this. This of course had me a little confused because I was always told that you could only use one filter. If your not sure what I am talking about lets look at the following example. The following example reads a directory named cfgrid and does not apply any filters and therefore will list the entire contents of the directory.

<cfset filters = "">
<cfdirectory action="list" directory="#ExpandPath('.')#/cfgrid" filter="#filters#" listinfo="name" name="dir">

<cfdump var="#dir#">

As you can see from the example above the entire directory is listed. The directory contains png,cfm & cfc file extensions. If we wanted to list just the png files we could apply a filter to the results.

<cfset filters = "*.png">
<cfdirectory action="list" directory="#ExpandPath('.')#/cfgrid" filter="#filters#" listinfo="name" name="dir">
<cfdump var="#dir#">

I was always told that you could only filter by one file extension. In fact this is right from the docs which would really back up that statement.

File extension filter applied to returned names, for example, *.cfm. One filter can be applied.

As I noted earlier you learn something new everyday. Here is an example of how to create multiple filters.

<cfset filters = "*.cfm|*.cfc">
<cfdirectory action="list" directory="#ExpandPath('.')#/cfgrid" filter="#filters#" listinfo="name" name="dir">

<cfdump var="#dir#">


ColdFusion 8 Grid Editor Select Menu

Word Count: 945

A couple weeks ago I wrote an tutorial on how to create a custom Grid Editor. The tutorial explained how you could tap into the power of Ext to create a select menu editor. In the example we used state as the edit field. This is a perfect example of where you would want to pick from a list rather than key in your answer. It has come to my attention that this functionality is baked right in to ColdFusion 8. This raises 1 important question for me, is nobody is reading my articles or did nobody know this was baked in?

So to get started with this tutorial you need a little knwoledge of how editing works with the html grid. Lucky for you I wrote a quick start on basic editing using the grid. The following code should look pretty similair if you have been following along. Here we are just running a query and setting up some basic properties for our grid. If you double click in any of the cells you should be able to edit the data.

<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">
<cfset args.selectmode = "edit">
<cfset args.onchange = "cfc:artists.editArtist({cfgridaction},{cfgridrow},{cfgridchanged})">

<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" >
</cfgrid>
</cfform>

The real power comes from the cfgridcolumn tag that has a couple of attributes that I did not know existed.

  • select - Determines selection behavior if the cfgrid selectmode attribute value is column, edit, or single; ignored for row or browse values.
  • values - Formats cells in column as drop-down list boxes; specify items in drop-down list, for example: values = "arthur, scott, charles, 1-20, mabel"
  • valuesDisplay - Maps elements in the values attribute to string to display in the drop-down list. Delimited strings and/or numeric ranges.

So with this knowledge you can set some values for a user to select from when editing a column. The great thing about this is we can grab our values from anywhere such as a list, query or even a web service. In my example I am just setting the state abbreviations and display values using lists.

<cfset state_abbr = "AL,AK,AZ,AR,CA,CO,CT,DE,DC,FL,GA,HI,ID,IL,IN,IA,KS,KY,LA,ME,MD,MA,MI,MN,MS,MO,MT,NE,NV,NH,NJ,NM,NY,NC,ND,OH,OK,OR,PA,RI,SC,SD,TN,TX,UT,VT,VA,WA,WV,WI,WY">
<cfset state_name = "Alabama,Alaska,Arizona,Arkansas,California,Colorado,Connecticut,Delaware,District of Columbia,Florida,Georgia,Hawaii,Idaho,Illinois,Indiana,Iowa,Kansas,Kentucky,Louisiana,Maine,Maryland,Massachusetts,Michigan,Minnesota,Mississippi,Missouri,Montana,Nebraska,Nevada,New Hampshire,New Jersey,New Mexico,New York,North Carolina,North Dakota,Ohio,Oklahoma,Oregon,Pennsylvania,Rhode Island,South Carolina,South Dakota,Tennessee,Texas,Utah,Vermont,Virginia,Washington,West Virginia,Wisconsin,Wyoming">

<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" width="125" select="true" values="#state_abbr#" valuesdisplay="#state_name#">
</cfgrid>
</cfform>

This makes it really easy to for you to create select menu editors. Here is a quick image of my example.

ColdFusion 9 Component Script

Word Count: 446

I know there are many users out there who love cfscript and many who really don't care for the syntax. I am really on the fence, I like the syntax but do not use it much because of the lack of support for certain tags and on the presentation layer it just does not mix well for me. One of the main reasons that Adobe is yet to support full scripting is the cfqueryparam tag. I am hoping that in the next version of ColdFusion they find a way to resolve this.

I have been doing some ActionScript 3 development lately and I really love the language. So with that I have a small proposal for CF9 that I am sure some people will be with and some are going to hate it. Day to day I write many Components so I think it would be really cool to write components using scripting. With that said here is an example of what I would like to be able to do.

<cfcomponent output="false" format="script">

   variables.dsn = "";

   public function init(String:dsn):User{
      variables.dsn = arguments.dsn;
      return this;
   }

   public function getUsers():query {
      var q = new cfquery();
      q.name = "q";
      q.datasource = variables.dsn;
      q.sql = "SELECT * FROM Users"
      q.execute();
      
      return q;
   }
   
   public function getUser(Numeric:id):Struct {
      var q = new cfquery();
      q.name = "q";
      q.datasource = variables.dsn;
      q.sql = "SELECT * FROM Users WHERE id = " + arguments.id;
      q.execute();
      
      return queryRowToStruct(q);
   }
   
</cfcomponent>

So go ahead rip it apart! Again this is just an idea and I would love to hear pros and cons of this approach from others.

ColdFusion 9 WishList Calling for suggestions

Word Count: 114

I would really like to find out what developers are looking for in the next version of ColdFusion. I am trying to put together a wish list to pass on to the engineering team (I know I am behind on this, sorry guys) and I am drawing a blank. I have a list of about 5 things right now so I could really use some feedback. After I get some feedback I will expand on this next week and we will see if we can grow this list to help the team out. Remember they are building the product for you, let your voice be heard!

CFGrid Event Listeners

Word Count: 1740

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.

<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">
   <cfset args.selectOnLoad = false>
   
   <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")>

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.

<script type="text/javascript">
function init(){
//get the grid component grid = ColdFusion.Grid.getGridObject("ArtistGrid");
</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?

<script type="text/javascript">
function init(){
   //get the grid component       grid = ColdFusion.Grid.getGridObject("ArtistGrid");
      
      //Fires when a row is clicked       grid.addListener("rowclick",editArtist);
      
}

function editArtist(grid,rowIndex,e){
   var record = grid.getDataSource().getAt(rowIndex);
   console.log(record);
}

</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

Word Count: 5712

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.

<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.width = 600>
<cfset args.format = "html">
<cfset args.query = "getArtists">
<cfset args.stripeRows = true>
<cfset args.selectColor = "##D9E8FB">
<cfset args.selectmode = "edit">
<cfset args.onchange = "cfc:artists.editArtist({cfgridaction},{cfgridrow},{cfgridchanged})">

<cfform>
<cfgrid attributeCollection="#args#">
<cfgridcolumn name="artistid" display="false">
<cfgridcolumn name="firstname" header="First Name">
<cfgridcolumn name="lastname" header="Last Name">
<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")>

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.

//grid object
grid = ColdFusion.Grid.getGridObject("ArtistGrid");
//column model cm = grid.getColumnModel();
//we need to know the column id 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.

cb = new Ext.form.ComboBox({
id:"state",
mode:"local",
triggerAction:"all",
displayField:"text",
valueField:"value",
store:new Ext.data.SimpleStore({
fields: ["value", "text"],
data: [
['AL', 'Alabama'],
['AK', 'Alaska'],
['AZ', 'Arizona'],
['AR', 'Arkansas'],
['CA', 'California'],
['CO', 'Colorado'],
['CT', 'Connecticut'],
['DE', 'Delaware'],
['DC', 'District of Columbia'],
['FL', 'Florida'],
['GA', 'Georgia'],
['HI', 'Hawaii'],
['ID', 'Idaho'],
['IL', 'Illinois'],
['IN', 'Indiana'],
['IA', 'Iowa'],
['KS', 'Kansas'],
['KY', 'Kentucky'],
['LA', 'Louisiana'],
['ME', 'Maine'],
['MD', 'Maryland'],
['MA', 'Massachusetts'],
['MI', 'Michigan'],
['MN', 'Minnesota'],
['MS', 'Mississippi'],
['MO', 'Missouri'],
['MT', 'Montana'],
['NE', 'Nebraska'],
['NV', 'Nevada'],
['NH', 'New Hampshire'],
['NJ', 'New Jersey'],
['NM', 'New Mexico'],
['NY', 'New York'],
['NC', 'North Carolina'],
['ND', 'North Dakota'],
['OH', 'Ohio'],
['OK', 'Oklahoma'],
['OR', 'Oregon'],
['PA', 'Pennsylvania'],
['RI', 'Rhode Island'],
['SC', 'South Carolina'],
['SD', 'South Dakota'],
['TN', 'Tennessee'],
['TX', 'Texas'],
['UT', 'Utah'],
['VT', 'Vermont'],
['VA', 'Virginia'],
['WA', 'Washington'],
['WV', 'West Virginia'],
['WI', 'Wisconsin'],
['WY', 'Wyoming']
]
})
});

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.

cm.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.

<cfsetting showdebugoutput="false">
<html>
<head>
<title>Edit Artist Grid</title>
<script type="text/javascript">
function init(){
//grid object grid = ColdFusion.Grid.getGridObject("ArtistGrid");
//column model cm = grid.getColumnModel();
//we need to know the column id stIndex = cm.findColumnIndex("STATE");

cb = new Ext.form.ComboBox({
id:"state",
mode:"local",
triggerAction:"all",
displayField:"text",
valueField:"value",
store:new Ext.data.SimpleStore({
fields: ["value", "text"],
data: [
['AL', 'Alabama'],
['AK', 'Alaska'],
['AZ', 'Arizona'],
['AR', 'Arkansas'],
['CA', 'California'],
['CO', 'Colorado'],
['CT', 'Connecticut'],
['DE', 'Delaware'],
['DC', 'District of Columbia'],
['FL', 'Florida'],
['GA', 'Georgia'],
['HI', 'Hawaii'],
['ID', 'Idaho'],
['IL', 'Illinois'],
['IN', 'Indiana'],
['IA', 'Iowa'],
['KS', 'Kansas'],
['KY', 'Kentucky'],
['LA', 'Louisiana'],
['ME', 'Maine'],
['MD', 'Maryland'],
['MA', 'Massachusetts'],
['MI', 'Michigan'],
['MN', 'Minnesota'],
['MS', 'Mississippi'],
['MO', 'Missouri'],
['MT', 'Montana'],
['NE', 'Nebraska'],
['NV', 'Nevada'],
['NH', 'New Hampshire'],
['NJ', 'New Jersey'],
['NM', 'New Mexico'],
['NY', 'New York'],
['NC', 'North Carolina'],
['ND', 'North Dakota'],
['OH', 'Ohio'],
['OK', 'Oklahoma'],
['OR', 'Oregon'],
['PA', 'Pennsylvania'],
['RI', 'Rhode Island'],
['SC', 'South Carolina'],
['SD', 'South Dakota'],
['TN', 'Tennessee'],
['TX', 'Texas'],
['UT', 'Utah'],
['VT', 'Vermont'],
['VA', 'Virginia'],
['WA', 'Washington'],
['WV', 'West Virginia'],
['WI', 'Wisconsin'],
['WY', 'Wyoming']
]
})
});

cm.setEditor(stIndex,new Ext.grid.GridEditor(cb));

}
</script>
</head>

<body>

<link href="/CFIDE/scripts/ajax/ext/resources/css/ytheme-aero.css" rel="stylesheet" type="text/css">

<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.width = 600>
<cfset args.format = "html">
<cfset args.query = "getArtists">
<cfset args.stripeRows = true>
<cfset args.selectColor = "##D9E8FB">
<cfset args.selectmode = "edit">
<cfset args.onchange = "cfc:artists.editArtist({cfgridaction},{cfgridrow},{cfgridchanged})">

<cfform>
<cfgrid attributeCollection="#args#">
<cfgridcolumn name="artistid" display="false">
<cfgridcolumn name="firstname" header="First Name">
<cfgridcolumn name="lastname" header="Last Name">
<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")>
</body>
</html>

ColdFusion Grid Editing Basic

Word Count: 1414

When the new grid features were announced in ColdFusion 8 people got very excited. I am not quite sure why but not to many people are talking about this feature these days. If you are new to grid editing support I encourage you to read an article by Ben Forta that outlines how to edit data in a grid. I am going to repeat some of that article but also show you a little more. Think of this as a refresher because the next tutorial I have will dive into some customization techniques.

Getting started with the tutorial we are going to stick with what got us here. I will be using the cfartgallery data source that ships with ColdFusion 8 so this should work out of the box. Here we have the code that creates our grid. There are only 2 attributes we need to add to our grid to make this work. First we set select mode to edit. This tells our grid to add editing capabilities. If we wanted to add deleting capabilities we could set the delete attribute to true but we will just be editing in this tutorial. The second difference is the the onChange attibute. We will look into this a little deeper in a second.

<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">
<cfset args.selectmode = "edit">
<cfset args.onchange = "cfc:artists.editArtist({cfgridaction},{cfgridrow},{cfgridchanged})">

<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>

Here is a how our grid turns out. You will notice that when you double click in a cell a text editor appears and after you make a change a red marker appears in the grid noting that the data has changed.

Now that we understand how to enable editing we need to cover how we actually save the changed data. If you look at the grid image you will notice that the last name Donolan now has a z on the end. If we enable firebug and take a look at the post we will see the following information. As you can see our grid passes 3 parameters; gridAction, gridRow and gridChanged. The gridAction argument will pass U for update and D for delete. The gridRow is a name value pair of the row being changed. Finally the gridChanged argument tells us what column is being changed and what the new value is.

{"gridaction":"U","gridrow":{"ARTISTID":1,"FIRSTNAME":"Aiden","LASTNAME":"Donolan","EMAIL":"aiden.donolan@donolan.com","ADDRESS":"352 Corporate Ave.","CITY":"Denver","STATE":"CO","POSTALCODE":"80206-4526","CFGRIDROWINDEX":1},"gridchanged":{"LASTNAME":"Donolanz"}}

If we look back at our code we should look at the onChange attribute. Here we are telling the grid that when the data changes we want to call our artists cfc and the method editArtist and into that method we are going to pass those 3 parameters.

<cfset args.onchange = "cfc:artists.editArtist({cfgridaction},{cfgridrow},{cfgridchanged})">

Finally here is the code from Ben's tutorial. If we get passed U for update we set the name of the column being changed and the new value and use that to update our database.

<cffunction name="editArtist" access="remote">
<cfargument name="gridaction" type="string" required="yes">
<cfargument name="gridrow" type="struct" required="yes">
<cfargument name="gridchanged" type="struct" required="yes">

<cfset var colname = "">
<cfset var value = "">

<cfswitch expression="#arguments.gridaction#">
<!--- update --->
<cfcase value="U">
<cfset colname = StructKeyList(arguments.gridchanged)>
<cfset value = arguments.gridchanged[colname]>

<cfquery datasource="#variables.dsn#">
UPDATE Artists
SET #colname# = '#value#'
WHERE artistid = <cfqueryparam value="#arguments.gridrow.artistid#" cfsqltype="cf_sql_integer">
</cfquery>
</cfcase>
<!--- delete --->
<cfcase value="D">
<cfquery datasource="#THIS.dsn#">
DELETE FROM Artists
where artistid = <cfqueryparam value="#arguments.gridrow.artistid#" cfsqltype="cf_sql_integer">
</cfquery>
</cfcase>
</cfswitch>

</cffunction>

As you can see editing inline on the grid is very easy to do. I see many question out there about customizing the editing features, stay tuned because I have something you are going to like.

ColdFusion 8 Grid Filtering

Word Count: 206

Over the past couple of weeks I have been writing quick tutorials on extending the built in AJAX components. Today I would like to show you an example that I believe everyone is going to find useful. Once you have a data grid displaying your data there are usually 2 key operations users will perform. The 1st is pagination of records which is built into the grid and is pretty easy to use. The 2nd is filtering or how can I find exactly what I am looking for without browsing all of the records. Most filter examples I have seen where built outside of the grid but I want to run through an example that builds a filter into the grid.

Before we get started I think we should take a look at the outcome, this way the tutorial makes a little more sense. I do not have 8 running so I will have to explain this using pictures. First we have a list of artists and I provide the user a way to filter the artists by what state they are in. When the state is selected the grid is updated.

[More]

Adding Custom Buttons to <cfwindow/>

Word Count: 525

The other day I wrote a short article on ColdFusion 8 custom grid toolbars. One reader had a question that I would like to share with you. Trond writes -

Do you know if a similar toolbar can be added to the bottom of a cfwindow?

The answer to this question is two fold. No there is not a panel are on the bottom like there is in the grid or even in the window components in Ext 2.0. This does not prevent you from customizing your windows though. You can add buttons to the window and I will show you how quickly you can do so. After the page loads I am using the ajaxOnLoad method to call my init method.

The first thing I need to do is create my window. You can see I have setup some basic properties on my window and using initShow=true will cause the window to show on page load.

<cfwindow name="MyWindow" center="true" closable="true" draggable="true" height="200" modal="true"
          initShow="false" minHeight="100" minWidth="200" resizable="true" title="Notify Administrator" width="400">

      Type Message here
   </cfwindow>

   <cfset ajaxonload("init")>

Here is the only part you need to wrap your head around. When we use the cfwindow tag ColdFusion imports all of the Ext framework libraries necessary to create the window. The button classes are not part of that include so we need to explicitly import them.

<script type="text/javascript" src="/CFIDE/scripts/ajax/ext/package/button/button.js"></script>

Now that we have our button class this is very simple. Here we have our init method that should run after the page is setup. Because there is no attribute of cfwindow for adding buttons we need to create an a event listener on the window. To do that we must first get the window object. After we have the window object we can say here is what we want you to do before you show the window component. The action we want it to do is to add a button. The window has a method for adding a button. The button takes a button config and you can learn more about that in the docs but its pretty straight forward. Finally we add a handler to our button that will call the method sayHello when its clicked.

<script language="JavaScript">
   function init(){
      myWindow = ColdFusion.Window.getWindowObject('MyWindow');
         
      myWindow.addButton({
         text:"My Button",
         cls:"x-btn-text-icon",
         icon:"add.png",
         handler:sayHello
      });
   }
   function sayHello(){
      alert("hello");
   }
   </script>

Hiding Columns In cfrgids Column Context Menu

Word Count: 286

I have been showing you how to extend the cfgrid component lately by tapping into the Ext framework. Earlier I wrote a tutorial about creating context menus. Henry liked it but had one concern, lets look at his 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"

Basically when you right click on the grids column header a menu will popup, in that menu their is a list of columns with check boxes next to the name so that you can hide/show columns in the grid. I can see why we need to hide the gridRowIndex. If someone has a better solution please let me know but I found a solution for this problem. Before the list of columns is shown we can loop over the list and search for the column we want to remove. Once we find the column simply use the menus remove method.

grid.view.colMenu.addListener("beforeshow", function(menu){         
         var grid = ColdFusion.Grid.getGridObject("ArtistGrid");
         var cm = grid.getColumnModel();
         var count = cm.getColumnCount();
         
         for(var i = 0; i < count; i++){
            if("CFGRIDROWINDEX" == cm.getDataIndex(i)) {
               menu.remove(menu.items["items"][i]);
            break;
            }
         }

      });

More Entries

Copyright © 2007 Dan Vega | BlogCFC was created by Raymond Camden. This blog is running version 5.8.001.