CRUD with cfgrid html format - Part 2

Tagged Under :

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.

Comments:

23 Responses to “CRUD with cfgrid html format - Part 2”


  1. [...] Anuj Gakhar has updated his CRUD application using ColdFusion 8’s ExtJS-driven CFGRID. There are a number of enhancements based on reader feedback. [...]


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


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


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


  5. 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?


  6. @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.


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


  8. @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.


  9. 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#


  10. @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.


  11. Where should I start? Can you give me some direction please?


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


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


  14. @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


  15. The way I was trying to go is….


  16. cfgridcolumn name=”PASSEDVAL” header=”Update” width=”60″ headeralign=”center” href=”#Request.Config.MidPath#Administration/Members/?action=edit&id=Id” hrefkey=”ID”


  17. I just want to add this link to each row returned to the grid
    Edit


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


  19. @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.


  20. [...] 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 [...]


  21. 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);

    }


  22. @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?


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

Leave a Reply