Using jQuery based jqGrid with ColdFusion Revisited: Full CRUD grid with Advanced Searching

It has been a while since I made my last blog post as work has kept me very busy. Over the weekend I saw that a new jqGrid version had been released and that it contained in-built advanced searching (called multiple search). I also thought it was a good time to revisit my earlier blog post on a full CRUD grid and update it to 3.6 specifications.


This implementation uses the following jqGrid features:

  1. Inbuilt Form based Add, Edit, Delete and Search functionality
  2. Search is done using new Multiple Search feature
  3. Exploration of a few additional colModel parameters

View the Demo : this is all realtime, any updates made will be reflected in the grid.
Now, lets look at the code

The HTML is still very simple.

   view plainprintabout
 <table id="list" class="scroll" cellpadding="0" cellspacing="0"></table>
 <div id="pager" class="scroll"></div>
Let's see the javascript that defines our grid.
   view plainprintabout
 <script>
         
     $(document).ready(function()
         {    
             $("#list").jqGrid(
             {
                 url:'Users2.cfc?method=getUsers', //CFC that will return the users
                 datatype: 'json', //We specify that the datatype we will be using will be JSON
                 colNames:['ID','First Name','Last Name', 'Display Name','User Name'], //Column Names
10                  //The Column Model to define the data. Note you can make columns non sortable, specify width, alignment, etc.
11                  colModel :[
12                      {name:'id',index:'id', width:75, sorttype:"int",editable:false,searchoptions:{sopt:['eq','lt','le','gt','ge']}},
13                      {name:'FirstName',index:'FirstName', width:150, sorttype:"text",searchoptions:{sopt:['eq','bw','ew','cn']},
14                          editable:true,edittype:"text",editoptions:{size:50},editrules:{required:true},formoptions:{elmprefix:"(*)"}},
15                      {name:'LastName',index:'LastName', width:150, align:"left",sorttype:"text",searchoptions:{sopt:['eq','bw','ew','cn']},
16                          editable:true,edittype:"text",editoptions:{size:50},editrules:{required:true},formoptions:{elmprefix:"(*)"}},
17                      {name:'DisplayName',index:'DisplayName', width:150, align:"left",sorttype:"text",searchoptions:{sopt:['eq','bw','ew','cn']},
18                          editable:true,edittype:"text",editoptions:{size:50},editrules:{required:true},formoptions:{elmprefix:"(*)"}},
19                      {name:'UserName',index:'UserName', width:150,align:"left",sorttype:"text",searchoptions:{sopt:['eq','bw','ew','cn']},
20                          editable:true,edittype:"text",editoptions:{size:50},editrules:{required:true},formoptions:{elmprefix:"(*)"}}
21                  ],//searchoptions parameter is used to limit the operators available during search
22                  pager: $('#pager'), //The div we have specified, tells jqGrid where to put the pager
23                  rowNum:20, //Number of records we want to show per page
24                  rowList:[20,30,40,50], //Row List, to allow user to select how many rows they want to see per page
25                  sortorder: "asc", //Default sort order
26                  sortname: "ID", //Default sort column
27                  viewrecords: true, //Shows the nice message on the pager
28                  imgpath: '/Test/themes/basic/images', //Image path for prev/next etc images
29                  caption: 'Users', //Grid Name
30                  recordtext: "Record {0} - {1} of {2}",//Pager information to show
31                  rownumbers: true,//Show row numbers
32                  rownumWidth: "40",//Width of the row numbers column
33                  sortable: true,
34                  height:'auto', //I like auto, so there is no blank space between. Using a fixed height can mean either a scrollbar or a blank space before the pager
35                  mtype:'POST',    
36                  toolbar:[true,"top"], //Shows the toolbar at the top. We will use it to display user feedback
37                  //The JSON reader. This defines what the JSON data returned from the CFC should look like
38                  jsonReader: {
39                      root: "ROWS", //our data
40   page: "PAGE", //current page
41   total: "TOTAL", //total pages
42   records:"RECORDS", //total records
43                      userdata:"USERDATA", //Userdata we will pass back for feedback
44                      cell: "", //Not Used
45                      id: "0" //Will default to first column
46                      },
47                  editurl:"Users2.cfc?method=addeditUser" //The Add/Edit function call                
48                  }                
49              ).navGrid('#pager',
50                  {
51                      search:true,searchtitle:"Search",//title set for hover over display
52                      edit:true,edittitle:"Edit User",
53                      add:true,addtitle:"Add User",
54                      del:true,deltitle:"Delete User"
55                  },
56              // Edit Options. savekey parameter will keybind the Enter key to submit.
57              {editCaption:"Edit User",edittext:"Edit",closeOnEscape:true, savekey: [true,13],errorTextFormat:commonError,width:"450"
58                  ,reloadAfterSubmit:true,bottominfo:"Fields marked with (*) are required",top:"60",left:"70"},
59              {addCaption:"Add User",closeOnEscape:true,savekey: [true,13],errorTextFormat:commonError,width:"450"
60                  ,reloadAfterSubmit:true,bottominfo:"Fields marked with (*) are required",top:"60",left:"70"}, //Add Options
61              {url:"Users2.cfc?method=delUser",caption:"Delete User",closeOnEscape:true,errorTextFormat:commonError,top:"60",left:"70",
62                  reloadAfterSubmit:true}, //Delete Options
63               //Search Options. multipleSearch parameter lets it know we are going to use the new advanced search feature
64              {errorTextFormat:commonError,Find:"Search",closeOnEscape:true,caption:"Search Users",multipleSearch:true,closeAfterSearch:true}
65              );            
66          
67          //Function will be called when add/edit encounters an error. The returned message is what will be shown to user    
68          function commonError(data)
69          {            
70              return "Error Occured during Operation. Please try again";
71          }
72              
73          }
74      );
75      </script>

Hopefully the comments in the code help understand what is going on. I am taking advantage of new colModel definitions that we can specify to help the multiple search feature. You can see this in the searchoptions parameter specification. The sopt array array specifies which operators can be associated with the search field, so for example, ID which is an integer can only handle equal, less than, less than equal to, greater than and greater than equal to operators. While the rest of the search fields which are text fields use operators more suited to text based searching.

We are also using the formoptions parameter and passing the elmprefix value. This value we have passed will be appended to our input elements. In this case we will use it to tell the user which fields are required.

In addition, we have specified additional parameters for the Add/Edit/Delete options. These include specifying the savekey (this is set to Enter, so pressing Enter will submit the Add/Edit form), closeOnEscape is set to true (you can close those modal dialogs with the Esc key). We have also specified our error handler for Add/Edit which is the function commonError. It will return a generic error message to the user. In order to use the multiple search implementation in jqGrid we have specified the multipleSearch parameter to true (so simple it is).

We also have our CFC component that will form the bridge between our grid and database.

   view plainprintabout
 <cfcomponent output="false">
     
     <cffunction name="getUsers" access="remote" returnformat="json">
         <cfargument name="page" required="no" default="1" hint="Page user is on">
      <cfargument name="rows" required="no" default="10" hint="Number of Rows to display per page">
      <cfargument name="sidx" required="no" default="" hint="Sort Column">
      <cfargument name="sord" required="no" default="ASC" hint="Sort Order">
      <cfargument name="nd" required="no" default="0">
      <cfargument name="_search" required="no" default="false">
10       <cfargument name="filters" required="no" default="">
11          
12          <cfset var arrUsers = ArrayNew(1)>
13          <cfset var strMsg = "">
14          <cfset var strMsgType = "Success">
15          <cfset var records = "">
16          <cfset var blnSearch = Arguments._search>
17          <cfset var strSearch = "">    
18          
19          <!--- Determine whether this a search call and if so build our search parameters --->
20          <cfif Arguments.filters NEQ "" AND blnSearch>
21              <cfset stcSearch = DeserializeJSON(Arguments.filters)>
22              <cfif isDefined("stcSearch.groupOp")>
23                  <cfset strSearch = buildSearch(stcSearch)>
24              </cfif>            
25          </cfif>
26          
27          <cfquery name="selUsers" datasource="RIADemo" result="res">
28              SELECT
29                  ID, FirstName, LastName, DisplayName, UserName
30              FROM
31                  Users
32              <cfif blnSearch AND strSearch NEQ "">
33                  #PreserveSingleQuotes(strSearch)#
34              </cfif>
35              ORDER BY #sidx# #sord#                
36          </cfquery>
37          
38          
39          
40          <cfset records = selUsers>
41          
42          
43          <!--- Calculate the Start Position for the loop query.
44          So, if you are on 1st page and want to display 4 rows per page, for first page you start at: (1-1)*4+1 = 1.
45          If you go to page 2, you start at (2-)1*4+1 = 5 --->

46          <cfset start = ((arguments.page-1)*arguments.rows)+1>
47          
48          <!--- Calculate the end row for the query. So on the first page you go from row 1 to row 4. --->
49          <cfset end = (start-1) + arguments.rows>
50          
51          <!--- When building the array --->
52          <cfset i = 1>
53          
54          <cfloop query="records" startrow="#start#" endrow="#end#">
55              <!--- Array that will be passed back needed by jqGrid JSON implementation --->        
56              <cfset arrUsers[i] = [#ID#,#FirstName#,#LastName#,#DisplayName#,#UserName#]>
57              <cfset i = i + 1>            
58          </cfloop>
59          
60          <!--- Calculate the Total Number of Pages for your records. --->
61          <cfset totalPages = Ceiling(records.recordcount/arguments.rows)>
62          
63          <!--- The JSON return --->
64          <cfset strReturn = {total=#totalPages#,page=#Arguments.page#,records=#records.recordcount#,rows=arrUsers}>
65          
66          <cfreturn strReturn>
67          
68      </cffunction>
69      
70      <cffunction name="addeditUser" access="remote" hint="Add or Edit User Data" returnformat="json">
71          <cfargument name="FirstName" required="yes" hint="Field that was Added or editted">
72          <cfargument name="LastName" required="yes" hint="Field that was Added or editted">
73          <cfargument name="DisplayName" required="yes" hint="Field that was Added or editted">
74          <cfargument name="UserName" required="yes" hint="Field that was Added or editted">        
75          <cfargument name="ID" required="yes" hint="the User that was Added or editted">
76          <cfargument name="oper" required="no" default="edit" hint="Whether this is an add or edit">
77          
78          <cfset var strMsg = "">
79          <cfset var strMsgType = "Success">
80          <cfset var userdata = "">
81          
82          <cfif oper EQ "edit">
83              <cfset strMsg = "User Editted">        
84              <!--- Take the data, update your record. Simple. --->
85              <cftry>
86                  <cfquery name="editUser" datasource="RIADemo">
87                      UPDATE
88                          Users
89                      SET
90                          FirstName = '#Arguments.FirstName#',
91                          LastName = '#Arguments.LastName#',
92                          DisplayName = '#Arguments.DisplayName#',
93                          UserName = '#Arguments.UserName#'                        
94                      WHERE
95                          ID = #Val(Arguments.ID)#
96                  </cfquery>
97              <cfcatch type="any">
98                  <!--- Error, return message --->
99                  <cfset strMsgType = "Error">
100                  <cfset strMsg = "Error Occured when editing user. An Error report has been submitted to support.">
101                  <cfthrow message="Error Occured During Edit">
102              </cfcatch>
103              </cftry>
104          <cfelse>
105              <cfset strMsg = "User Added">
106              <cftry>                
107              <cfquery name="addUser" datasource="RIADemo">
108                  INSERT INTO USERS(FirstName,LastName,DisplayName,UserName)
109                  VALUES ('#Arguments.FirstName#','#Arguments.LastName#','#Arguments.DisplayName#','#Arguments.UserName#')
110              </cfquery>
111              <cfcatch>
112                  <!--- Error, return message --->
113                  <cfset strMsgType = "Error">
114                  <cfset strMsg = "Error occured when Adding User. An Error report has been submitted to support.">
115                  <cfthrow message="Error Occured During Add">
116              </cfcatch>
117              </cftry>
118          </cfif>
119          <!--- We just need to pass back some user data for display purposes --->
120          <cfset userdata = {type="#strMsgType#",msg="#strMsg#"}>
121          <cfset strReturn = {userdata=#userdata#}>
122          
123          <cfreturn strReturn>
124          
125      </cffunction>
126      
127      <cffunction name="delUser" access="remote" hint="Delete Selected User" returnformat="json">        
128          <cfargument name="id" required="yes" hint="id to delete">
129          
130          <cfset var strMsg = "">
131          <cfset var strMsgType = "Success">
132          <cfset var userdata = "">
133          <cfset var delUser = "">
134          
135          <cftry>
136              <cfset strMsg = "Deleted User">
137              <cfquery name="delUser" datasource="RIADemo">
138                  DELETE FROM Users WHERE ID = #Val(Arguments.id)#
139              </cfquery>
140          <cfcatch>
141              <!--- Error, return message --->
142              <cfset strMsgType = "Error">
143              <cfset strMsg = "Error occured when Deleting User. An Error report has been submitted to support.">
144          </cfcatch>
145          </cftry>
146          
147          <cfset userdata = {type="#strMsgType#",msg="#strMsg#"}>
148          <cfset strReturn = {userdata=#userdata#}>
149          
150          <cfreturn strReturn>
151          
152      </cffunction>
153      
154      <cffunction name="buildSearch" access="private" hint="Build our Search Parameters">
155          <cfargument name="stcSearch" required="true">
156          
157          <!--- strOp will be either AND or OR based on user selection --->
158          <cfset var strOp = stcSearch.groupOp>
159          <cfset var arrFilter = stcSearch.rules>
160          <cfset var strSearch = "">
161          <cfset var strSearchVal = "">
162          
163          <!--- Loop over array of passed in search filter rules to build our query string --->
164          <cfloop array="#arrFilter#" index="arrIndex">
165              <cfset strField = arrIndex["field"]>
166              <cfset strOp = arrIndex["op"]>
167              <cfset strValue = arrIndex["data"]>
168              
169              <cfset strSearchVal = buildSearchArgument(strField,strOp,strValue)>
170              
171              <cfif strSearchVal NEQ "">
172                  <cfif strSearch EQ "">
173                      <cfset strSearch = "WHERE (#PreserveSingleQuotes(strSearchVal)#)">
174                  <cfelse>
175                      <cfset strSearch = strSearch & "#strOp# (#PreserveSingleQuotes(strSearchVal)#)">                
176                  </cfif>
177              </cfif>
178              
179          </cfloop>
180          
181          <cfreturn strSearch>
182                  
183      </cffunction>
184      
185      <cffunction name="buildSearchArgument" access="private" hint="Build our Search Argument based on parameters">
186          <cfargument name="strField" required="true" hint="The Field which will be searched on">
187          <cfargument name="strOp" required="true" hint="Operator for the search criteria">
188          <cfargument name="strValue" required="true" hint="Value that will be searched for">
189          
190          <cfset var searchVal = "">
191          
192          <cfif Arguments.strValue EQ "">
193              <cfreturn "">
194          </cfif>
195          
196          <cfscript>
197              switch(Arguments.strOp)
198              {
199                  case "eq":
200                      //ID is numeric so we will check for that
201  
                    if(Arguments.strField EQ "id")
202                      {
203                          searchVal = "#Arguments.strField# = #Arguments.strValue#";
204                      }else{
205                          searchVal = "#Arguments.strField# = '#Arguments.strValue#'";
206                      }
207                      break;                
208                  case "lt":
209                      searchVal = "#Arguments.strField# < #Arguments.strValue#";
210                      break;
211                  case "le":
212                      searchVal = "#Arguments.strField# <= #Arguments.strValue#";
213                      break;
214                  case "gt":
215                      searchVal = "#Arguments.strField# > #Arguments.strValue#";
216                      break;
217                  case "ge":
218                      searchVal = "#Arguments.strField# >= #Arguments.strValue#";
219                      break;
220                  case "bw":
221                      searchVal = "#Arguments.strField# LIKE '#Arguments.strValue#%'";
222                      break;
223                  case "ew":                    
224                      searchVal = "#Arguments.strField# LIKE '%#Arguments.strValue#'";
225                      break;
226                  case "cn":
227                      searchVal = "#Arguments.strField# LIKE '%#Arguments.strValue#%'";
228                      break;
229              }            
230          
</cfscript>
231          
232          <cfreturn searchVal>
233      
234      </cffunction>
235      
236  </cfcomponent>

Source Code (cfm/cfc) Here.
Feel free to contact me if you have any questions and I will try to help you out.

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
Sebastiaan's Gravatar Hi, cool thingy, seems like it does the same stuff cfgrid does, only probably a bit slicker. I miss a multiple delete though. I can only select one row to delete whilest the messagebox popping up on delete asks me if I want to delete the record(s). I'm on Opera 10.10.
# Posted By Sebastiaan | 12/9/09 7:40 AM
Kumar's Gravatar You can enable multiselect on jqGrid with specifying the multiselect:true parameter for the grid definition.
# Posted By Kumar | 12/9/09 10:18 PM
udip's Gravatar thanks for the great example. One question I had was I am trying to do multiple file upload when you click on "Add" or "edit" buttons. Is there any easy way to accomplish that. It would be awesome if the "Add" or "edit" windows open up a new page or a div in the same page so I can easily add this multiple file upload.
# Posted By udip | 12/14/09 2:54 AM
Kumar Shah's Gravatar @udip,
Ray Camden has a good post on using jQuery and ColdFusion for multiple file uploading:
http://www.coldfusionjedi.com/index.cfm/2009/11/20...
# Posted By Kumar Shah | 12/14/09 10:42 AM
udip's Gravatar Kumar, let me rephrase my question, when user clicks on "Add" or "Edit", I want it to
open in a new window. Similar to cfwindow so I can easily add custom fields in there.
# Posted By udip | 12/14/09 5:28 PM
Kumar Shah's Gravatar You can certainly do that. If you look at this post (http://www.coldfusion-ria.com/Blog/index.cfm/2009/...) you will notice that I pop up a custom search screen when the user clicks on the Search button.

jqGrid provides functions to add your own buttons to the navigation bar, and also what you do when someone clicks on it.
# Posted By Kumar Shah | 12/14/09 6:46 PM
Jim Console's Gravatar Great stuff! Can I make one of the columns linkable (per entry)? There are a few other tweaks I would like to make, but it looks like to me that jquery.jqGrid.min.js is a honkin' file that may take me a bit to master - let alone the jquery lib. Is there documentation that would flatten my learning curve?
# Posted By Jim Console | 12/15/09 9:46 PM
Kumar's Gravatar @Jim, check the jqGrid documentation (http://www.trirand.com/jqgridwiki/doku.php?id=wiki...). Especially, the Formatter documenation at http://www.trirand.com/jqgridwiki/doku.php?id=wiki...

It should have a way to make the data appear as a link to a specified target.
# Posted By Kumar | 12/15/09 11:07 PM
Jim Console's Gravatar Kumar,
I am pretty new to JQuery, and not all that strong with JS, especially debugging (noob disclaimer) - When I run your example through Firebug I get "$ is not defined" on the line $(document).ready(function()" - the first line. It seems to me that I am missing a dependency somewhere, but I know I have the three JS files ref'd correctly as I have copied them into the cfm directory and removed "js/" from src reference.
# Posted By Jim Console | 12/21/09 2:43 PM
Sung's Gravatar Looks like only the first filter is working -- any subsequent filters are ignored...
# Posted By Sung | 12/21/09 3:13 PM
Kumar Shah's Gravatar @Jim, that error means that the jQuery file is not referenced properly. I would urge you to recheck you have got all the js files and also check with Firebug to see that the jquery js file is being included properly. If you are still having issues, contact me and we will exchange your code and I will take a look at it.

@Sung, you are right about that, I forgot the update the CFC to handle multiple filter parameters. Will work on that this week.
# Posted By Kumar Shah | 12/21/09 3:36 PM
Patrick's Gravatar Hi! Thanks for this great example. I try to add the "ondblClickRow" function for make the edit box appear on double click instead of the small pen at the bottom. Do you know how ? Can you make a example from your demo code ?
Thank you!
# Posted By Patrick | 2/19/10 12:37 AM
Patrick's Gravatar sorry.. after make a few test... i got it!
# Posted By Patrick | 2/22/10 7:26 PM
Daniel's Gravatar I using jggrid with CF/ColdBox a lot... jgGrid is very flexible <ns it's amazing what you all can do... but I run also several times into some bugs which were a bit annoying. But the folks there do a good job with regular updates and fixes... I would have time, I would try do integrate it into CF-Wrapper as they do with ASP and PHP... just to make it more easy to use ;-)
# Posted By Daniel | 3/17/10 4:31 PM
Jeffrey Smith's Gravatar I have a nice app going with jqGrid but I am hung up on a small detail. In the Grid Column for "date_birth_anl" my value shows for example "April, 01 2010 00:00:00".

I am using mySql at the field is a "date" type.

Of course I would like something like "mm/dd/yyyy" at the presentation level. I have looked at the formater but no luck. To be sure I downloaded the full options using jqGrid Download Manager (v jquery.jqGrid-3.6.4). I suspect I am missing a function.

I don't get errors but my following colMod for the date has no effect: but also throws no errors in Firebug.

{ name: 'date_birth_anl', index: 'date_birth_anl', width: 100, editable: true, sorttype:'date', formatter:{date:{srcformat: 'Y-m-d H:i:s', neweformat: 'm-d-y'}},formoptions:{elmprefix:"&nbsp;&nbsp;&nbsp;&nbsp;"},
editoptions: { size: 22, dataInit: function(el) {
$(el).datepicker({ dateFormat: 'yy-m-dd',changeMonth:true,changeYear:true}) ;
      }
   }

Any suggestions are much appreciated.

Jeffrey
# Posted By Jeffrey Smith | 4/8/10 7:50 PM
Jeffrey Smith's Gravatar I figured out my earlier "date" format issue in jqGrid.

I went to my CFC and added a "DateFormat" function in the Query Loop.

<cfloop query="records" startrow="#start#" endrow="#end#">
         <!--- Array that will be passed back needed by jqGrid JSON implementation --->      
         <cfset arrAnimals[i] = [#id_anl#,#name_anl#,DateFormat(#date_birth_anl#, "mm-dd-yyyy"),#label_gdr#,#label_spc#,#label_spt#]>
         <cfset i = i + 1>         
      </cfloop>

After that my presentation as well as my datepicker all worked to Add/Edit off the jqGrid with the format I was looking for.

Thanks,
J
# Posted By Jeffrey Smith | 4/8/10 8:27 PM
David Gentry's Gravatar First of all, thanks for this example, it's been a great help!

There's a bug in the example cfc preventing multiple search from working: The same variable name, "strOp" is being used for both the group operator (e.g., "AND" or "OR") and the comparison operator (e.g., "bw", "eq", "lt", etc.) - so there's variable collision.

Fix -

Change line 158 to read:
<cfset var strGroupOp = stcSearch.groupOp>

Then change line 175 to read:
<cfset strSearch = strSearch & "#strGroupOp# (#PreserveSingleQuotes(strSearchVal)#)">
# Posted By David Gentry | 6/15/10 2:44 PM
Chris Bowyer's Gravatar Very impressive! However, is there a script for the database somewhere?
# Posted By Chris Bowyer | 6/28/10 3:21 AM
Joe's Gravatar I tried to implement the jqGrid using the code you provided. The only thing I changed is the cfc call.
When the page loads, it gives "Object doesn't support this property or method" on line "$("#list").jqGrid(". However, the Grid loaded fine. i was able to see and sort columns.

Another problem is the "add" and "edit" button does not show at all.

Do you know what am I missing?

Here is my code:

$(document).ready(function()
{
$("#list").jqGrid(
{
url:'/cfc/Campaign.cfc?method=getData', //CFC that will return the users
datatype: 'json', //We specify that the datatype we will be using will be JSON
colNames:['CampaignID','Name','Start Date', 'Expiration Date', 'Notes'], //Column Names
//The Column Model to define the data. Note you can make columns non sortable, specify width, alignment, etc.
colModel :[
    {name:'CampaignID',index:'CampaignID', width:100, sortable:false ,editable:false},
{name:'Name',index:'Name', width:150, sorttype:"text",editable:false,searchoptions:{sopt:['eq','bw','ew','cn']}},
{name:'StartDate',index:'StartDate', width:120, sorttype:"text",
editable:true,edittype:"text",editoptions:{size:50},editrules:{required:true},formoptions:{elmprefix:"(*)"}},
{name:'Expires',index:'Expires', width:120, align:"left",sorttype:"text",
editable:true,edittype:"text",editoptions:{size:50},editrules:{required:true},formoptions:{elmprefix:"(*)"}},
{name:'Notes',index:'Notes', width:450,align:"left",sortable:false,
editable:true,edittype:"text",editoptions:{size:50},editrules:{required:true},formoptions:{elmprefix:"(*)"}}
],//searchoptions parameter is used to limit the operators available during search
pager: $('#pager'), //The div we have specified, tells jqGrid where to put the pager
rowNum:20, //Number of records we want to show per page
rowList:[20,30,40,50], //Row List, to allow user to select how many rows they want to see per page
sortorder: "asc", //Default sort order
sortname: "CampaignID", //Default sort column
viewrecords: true, //Shows the nice message on the pager
imgpath: 'css/ui-lightness/images', //Image path for prev/next etc images
caption: 'Campaigns', //Grid Name
recordtext: "Record {0} - {1} of {2}",//Pager information to show
rownumbers: true,//Show row numbers
rownumWidth: "40",//Width of the row numbers column
sortable: true,
height:'auto', //I like auto, so there is no blank space between. Using a fixed height can mean either a scrollbar or a blank space before the pager
mtype:'POST',
toolbar:[true,"top"], //Shows the toolbar at the top. We will use it to display user feedback
//The JSON reader. This defines what the JSON data returned from the CFC should look like
jsonReader: {
root: "ROWS", //our data
                page: "PAGE", //current page
                total: "TOTAL", //total pages
                records:"RECORDS", //total records
campaigndata:"CAMPAIGNDATA", //campaigndata we will pass back for feedback
cell: "", //Not Used
id: "0" //Will default to first column
},
editurl:"/cfc/Campaign.cfc?method=addeditCampaign" //The Add/Edit function call
}
).navGrid('#pager',
{
edit:true,edittitle:"Campaign User",
add:true,addtitle:"Add Campaign"
},
// Edit Options. savekey parameter will keybind the Enter key to submit.
{editCaption:"Edit Campaign",edittext:"Edit",closeOnEscape:true, savekey: [true,13],errorTextFormat:commonError,width:"450"
,reloadAfterSubmit:true,bottominfo:"Fields marked with (*) are required",top:"60",left:"70"},
{addCaption:"Add Campaign",closeOnEscape:true,savekey: [true,13],errorTextFormat:commonError,width:"450"
,reloadAfterSubmit:true,bottominfo:"Fields marked with (*) are required",top:"60",left:"70"} //Add Options

);

//Function will be called when add/edit encounters an error. The returned message is what will be shown to user
function commonError(data)
{
return "Error Occured during Operation. Please try again";
}

}
);
# Posted By Joe | 7/7/10 7:38 PM
miked's Gravatar I had to set the type in the cfargument for _search to make the search work:

<cfargument name="_search" required="no" default="false" type="boolean">
# Posted By miked | 7/16/10 7:10 PM
BlogCFC was created by Raymond Camden. This blog is running version 5.9.5.003.  Design based on ARCLITE by: digitalnature