CRUD with cfgrid html format - Part 2
Tagged Under : ColdFusion
In response to reader’s comments from my previous post, I have updated the code for this little thingy.
Here are the updates in this version.
1) Added the ability to change pagesize dynamically (I did a separate post on this one earlier)
2) Made the grid rows double clickable. On double click, a window opens up with the selected row which can then be updated.
3) Removed the inline editing as didnt want the confusion of inline editing and double clickable rows.
4) The same “Add Artist” is used for add/update.
5) Changed the CFC to accomodate the update functionality.
6) Fixed a couple bugs and general code optimization and added some more comments in the code.
Any questions, please ask.
Oh, here is the code.
And for those, who want to see how it looks now, before trying, here is a little screen grab.

[...] Anuj Gakhar has updated his CRUD application using ColdFusion 8’s ExtJS-driven CFGRID. There are a number of enhancements based on reader feedback. [...]
Hi Anuj, this is a great example, but I can’t seem to get it to work in IE7. I get “‘dataproxy’ is null or not an object” any help is greatly appreciated.
Hi Jason,
Thanks.
Actually, I should have noticed this myself. Its an IE thing as explained here. http://www.coldfusionjedi.com/index.cfm/2008/7/1/IE-issue-with-AjaxProxy
The solution is to change this line
var dataproxy = new dataproxy();
to this
var dataproxy = new cfcproxy();
Because having the same name for the proxy and the variable breaks things, apaprently.
Hope that helps.
Just to make it clear,
you first call the cfajaxproxy tag like this.
<cfajaxproxy cfc=”data” jsclassname=”cfcproxy”> (notice i changed the name to cfcproxy .
And then in your JS
var dataproxy = new cfcproxy();
let me know if it still doesnt work.
Thanks for doing this example! I’ve been trying to figure out how to use grids since I got CF 8.
I’m trying to follow along by using my own data. One of my fields is an integer type. When I try to add a record, I get the following error:
Error invoking CFC /cfusion/schooltest/components/schools.cfc : The YEAR_STARTED argument passed to the addNewSchool function is not of type integer. [Enable debugging by adding 'cfdebug' to your URL parameters to see more information]
Is there anything different I need to do in the add window? I have even tried to use the parseInt() function around my variable. Any suggestions?
@Jeff, looks like something you will have to debug. Try debugging and see what values are being passed in to the CFC, or show me your code and I can take a look.
Hi,
I haven’t started yet, but I’m going to use your code but change the drop down box to filter the grid by a specific columns. Any examples or suggestions? BTW I’m loving your blog! WOOHOO!!
@knk, are you saying you want to control which columns you want to hide/show ? If yes, I think there is something already tehre in the Ext library for that. Will have to search a bit.
And, glad that you are liking the blog.
Thanks for the nice words.
So I have 3 files now that consist of the JS, form and the component. The grid is working and filtering but it’s only filtering the data on that page. It’s not filtering all the data. How can I fix this? Here’s my code:
JS:
function init(){
grid = ColdFusion.Grid.getGridObject(”MemberGrid”);
//var gridFoot = grid.getView().getFooterPanel(true); //make the footer
var gridHead = grid.getView().getHeaderPanel(true); //make the header so I can add button and CB
var tbar = new Ext.Toolbar(gridHead);
cb = new Ext.form.ComboBox({
id:”AccountFilter”,
emptyText:”Filter By Account Status”,
mode:”local”,
triggerAction:”all”,
displayField:”text”,
valueField:”value”,
store:new Ext.data.SimpleStore({
fields: ["value", "text"],
data: [
["Active","Active"],
["Inactive","Inactive"],
["Historical","Historical"],
["Guest","Guest"],
]
})
});
cb.addListener(”select”,function(combo,record,index){
var AccountStatus = record.data.value;
var AccountStatus2 = record.data.text;
grid.getDataSource().filter(”ACCOUNTSTATUS”,AccountStatus); //fi
});
Ext.fly(tbar.addSpacer().getEl().parentNode).setStyle(’width’, ‘100%’);
tbar.addButton({
text:”Remove Filter”,
icon:”plugin.png”,
cls:”x-btn-text-icon”,
tooltip:”Remove Filter”,
handler:removeFilter
});
tbar.add(new Ext.Toolbar.Separator());
tbar.add(cb);
console.log(Ext);
}
function removeFilter(){
store = grid.getDataSource()
store.clearFilter();
cb.clearValue(); //clear the value of the combo box
cb.reset(); //reset it so empty text shows up
}
CFFORM:
CFC:
SELECT
m.Id AS id,
m.LastName + ‘, ‘ + m.FirstName AS FullName,
m.CompanyId,
m.EmailAddress,
m.WorkPhone,
c.Name AS CompanyName,
p.Name AS PositionName,
acstat.Name AS AccountStatus,
acstat.id as StatusID,
getdate() as currenttime
FROM
nma_Members AS m INNER JOIN
nma_Companies AS c ON m.CompanyId = c.Id INNER JOIN
nma_AccountStatuses AS acstat ON m.AccountStatusId = acstat.Id INNER JOIN
nma_Positions AS p ON m.PositionId = p.Id
order by #gridsortcolumn# #gridsortdirection#
@knk, you are filtering on whats available and thats just the page you see, so whats happening is right. In order to do a server-side filter, you would have to call the CFC and reload the grid data.
Where should I start? Can you give me some direction please?
instead of this line
grid.getDataSource().filter(”ACCOUNTSTATUS”,AccountStatus); //fi
you would do
grid.reload({AccountStatus});
and make sure the CFc would accept that parameter and run the wuery based on that.
Something like that would work.
Hi,
Another question. I want to add another column to grid that has a hyperlink called Edit. Each row will have a Edit link. I can’t seem to make the href attributes work correctly. I added the column on but it just displays a small line in the column I added? Any Suggestions?
Thanks
@knk, Probably you need a cell renderer.
function renderLink(val, p, record, rowIndex, columnIndex, ds)
{
var html = ‘‘ + val + ‘‘;
return html;
}
and while putting the column
header: “your header”,
dataIndex: ‘dataindex’,
width: 50,
renderer: renderLink
The way I was trying to go is….
cfgridcolumn name=”PASSEDVAL” header=”Update” width=”60″ headeralign=”center” href=”#Request.Config.MidPath#Administration/Members/?action=edit&id=Id” hrefkey=”ID”
I just want to add this link to each row returned to the grid
Edit
The work around that I did was just adding a href to an existing column. One problem that I ran into was passing the CFGRIDKEY in the Url. I was able to fix that by using this
I’m still curious and interested on adding another column and just using text or passing a string to use as a link.
@knk, href and hrefkey should work just fine.
<cfgridcolumn name=”PASSEDVAL” header=”Update” width=”60″ headeralign=”center” href=”#Request.Config.MidPath#Administration/Members/?action=edit” hrefkey=”ID” >
this should correctly make your column a link.
[...] public links >> crud CRUD with cfgrid html format - Part 2 Saved by PlanMaestro on Fri 24-10-2008 Crud…. Saved by amistad on Fri 24-10-2008 Bitter SOA [...]
Anuj,
I used your code as the basis for my grid. Some of my data in the columns are links to other pages using the href parameter of the cfgridcolumn. If the data for the row is null, the grid puts a space in the cell and I get a _ (link) in the cell.
I tried to catch the null with a listner put can’t seem to get the right solution. How can I do this?
Thanks, Jim
Here’s my code.
Test Shipping Grid
// create a new JS proxy object for the CFC
var dataproxy = new cfcproxy();
dataproxy.setCallbackHandler(handleResult);
// this function recieves the response from CFC whenever a CFC function is called.
// we are simply alerting the response but we could do more if we had to.
function handleResult(response)
{
alert(response);
}
var myf = function(data,cellmd,record,row,col,store) {
if(data == ” “) return “”;
else return data;
}
// the init()
function init(){
grid = ColdFusion.Grid.getGridObject(”ShipGrid”);
cm = grid.getColumnModel();
cm.setRenderer(9, Ext.util.Format.usMoney);
cm.setRenderer(2,myf);
grid.reconfigure(grid.getDataSource(),cm);
// get the header and fotoer objects
var gridHead = grid.getView().getHeaderPanel(true);
var tbar = new Ext.Toolbar(gridHead);
var gridFoot = grid.getView().getFooterPanel(true);
var ds = grid.getDataSource();
// add the 2 custom buttons to the toolbar
//tbar.addButton({text:”Add Artist”, handler:onAdd });
// tbar.addSeparator();
// tbar.addButton({ text:”Delete Artist”, handler:onDelete });
// add a row double click event for the grid rows.
// the double click will open a popup window for editing the row.
//var sm = grid.getSelectionModel();
//grid.on(’rowdblclick’,function(grid, rowIndex, record){
// var rec = ds.getAt(rowIndex); // get the clicked row
// populateForm(rec); // populate the form with values
// ColdFusion.Window.show(’addArtistWin’); // display the window
// });
// this shows the display message by default
var paging = new Ext.PagingToolbar(gridFoot,ds,{
pageSize:10, //number of records displayed in grid
displayInfo:true, // change this to false, if you dont want info displayed
displayMsg:’Displaying records {0} - {1} of {2}’,
emptyMsg:”No records to display”
});
// add a custom combobox to the grid header - this combobox lets you choose the number of rows you want to see
cb = new Ext.form.ComboBox({
id:”pagingCombo”,
emptyText:”Rows per page”,
mode:”local”,
triggerAction:”all”,
displayField:”text”,
valueField:”value”,
store:new Ext.data.SimpleStore({
fields: ["value", "text"],
data: [
["5","5 rows per page"],
["10","10 rows per page"],
["15","15 rows per page"],
["20","20 rows per page"],
["30","30 rows per page"]
]
})
});
// add event listener to combobox
// this code will update the grid pageSize
cb.addListener(”select”,function(combo,record,index){
// the new pageSize from combobox - it needs to have parseInt() else it starts acting weird
var numRows = parseInt(record.data.value);
paging.pageSize = parseInt(numRows);
paging.onClick(”refresh”);
});
// add the paging combo to right side of the toolbar
Ext.fly(tbar.addSpacer().getEl().parentNode).setStyle(’width’, ‘100%’);
tbar.add(cb);
}
@Jim, Sorry your comment was stuck in spam and I just noticed. So, is the problem solved or not yet? did you try alerting mycf to see what it was returning?
Yes, I did solve my problem of having a null linked in a cell. You need to do the link with a function, which gives you and opportunity to also intraigate the data and link accordingly. I also found how to control the column alignment with css. Below is my current code.
One last question to answer: If columns are moved, how can I save the grid structure and then restore it on the next visit to the page?
Test Shipping Grid
// create a new JS proxy object for the CFC
var dataproxy = new cfcproxy();
dataproxy.setCallbackHandler(handleResult);
// this function recieves the response from CFC whenever a CFC function is called.
// we are simply alerting the response but we could do more if we had to.
function handleResult(response)
{
alert(response);
}
var myf1 = function(data,cellmd,record,row,col,store) {
if(data > “”) return “” + data + ““;
else return data;
}
var myf2 = function(data,cellmd,record,row,col,store) {
if(data > “”) return “” + data + ““;
else return data;
}
var myf3 = function(data,cellmd,record,row,col,store) {
if (( data != “AUTOMATIC”) && (data > “”)) return “” + data + ““;
else return data;
}
// the init()
function init(){
grid = ColdFusion.Grid.getGridObject(”ShipGrid”);
cm = grid.getColumnModel();
cm.setRenderer(1,myf1);
cm.setRenderer(2,myf2);
cm.setRenderer(3,myf3);
cm.setRenderer(9, Ext.util.Format.usMoney);
grid.reconfigure(grid.getDataSource(),cm);
// get the header and fotoer objects
var gridHead = grid.getView().getHeaderPanel(true);
var tbar = new Ext.Toolbar(gridHead);
var gridFoot = grid.getView().getFooterPanel(true);
var ds = grid.getDataSource();
// this shows the display message by default
var paging = new Ext.PagingToolbar(gridFoot,ds,{
pageSize:10, //number of records displayed in grid
displayInfo:true, // change this to false, if you dont want info displayed
displayMsg:’Displaying records {0} - {1} of {2}’,
emptyMsg:”No records to display”
});
// add a custom combobox to the grid header - this combobox lets you choose the number of rows you want to see
cb = new Ext.form.ComboBox({
id:”pagingCombo”,
emptyText:”Rows per page”,
mode:”local”,
triggerAction:”all”,
displayField:”text”,
valueField:”value”,
store:new Ext.data.SimpleStore({
fields: ["value", "text"],
data: [
["5","5 rows per page"],
["10","10 rows per page"],
["15","15 rows per page"],
["20","20 rows per page"],
["30","30 rows per page"]
]
})
});
// add event listener to combobox
// this code will update the grid pageSize
cb.addListener(”select”,function(combo,record,index){
// the new pageSize from combobox - it needs to have parseInt() else it starts acting weird
var numRows = parseInt(record.data.value);
paging.pageSize = parseInt(numRows);
paging.onClick(”refresh”);
});
// add the paging combo to right side of the toolbar
Ext.fly(tbar.addSpacer().getEl().parentNode).setStyle(’width’, ‘100%’);
tbar.add(cb);
}
.x-grid-hd {text-align:center;}
.x-grid-col {text-align:center;}
.x-grid-col-9 {text-align:right;}
Select Column
Sale Order
Ship Number
Invoice Number
Carrier
Waybill Number
Ship Date >