jqGrid: The hard way


I have been using the jQuery jqGrid plug-in quite a bit lately and I would have to say it is one of the best data grids I have used.  However, if you are pulling your data from a local array, until you are familiar with the inner workings of the plug-in it can be a bit intimidating.

Currently I am working on a project and they would like a “Top 10” list of products.  You can adjust the ranking of a product by moving the products position in the table up or down, you can delete products from the list entirely and finally, have the ability to add a new product to the list.  Working with live data this really would be a non-issue, any of the logic to handle moving data would be written in your SQL.  In this project I do not have access to an ajax back end so I have to handle everything client side.  When the form gets posted I  update a form field with the table values.

With a standard table element it is very easy to insert and delete rows.  The jqGrid plug-in also makes this easy with addRowData() and delRowData() methods.  The one difference however is jqGrid expects a row  id to be passed that it uses to identify the row you want to add or delete.  Row id’s are always changing based on how you are sorting your grid so the selected row in the table may not necessarily match the row id.  To get around this I disabled the sortable options on my rows.  I set a sort based on the Rank (id) so when the grid is refreshed it will always be listed in ascending order.

Another issue I chose to deal with is that I like all my row id’s sequential.  If I have 10 elements in my table and I delete the third element, I want all the remaining elements re-indexed accordingly.  It is a nit-picky thing, but this script does handle re-indexing the array elements.  After deleting the selected row from the table  I store the rowData structure of each table row in an array and then call the clearGridData() method to clear the grid.  I then loop over the data array setting the id to the current table row and then add the row by calling addRowData().

Moving the rows up and down is not all that complicated.  You will need to know the row id for the row you want to move so we need the array values from getRowIDs().  The current row id is calculated as getRowIDs()[ $(‘jquery object’).getGridParam(‘selrow’) – 1 ].  From there you just need to copy the current row and the previous or next rows row data depending on whether you want to move the selected row down or up in the sort.

I have included my proof-of-concept code.  Most of the tutorials and I read out there were all based on hooking jqGrid to an ajax data source so if someone is out there struggling working on some client side code, hopefully this will help you out.  I left most of my debugging functions in there in case you would like to play around with them as well.  A ColdFusion loop populates the test data so if you are not using ColdFusion you will probably want to hard-code some data in. 😛

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Untitled Document</title>
<link rel="stylesheet" type="text/css" media="screen" href="/css/redmond/jquery-ui-1.7.2.custom.css" />
<link rel="stylesheet" type="text/css" media="screen" href="/css/ui.jqgrid.css" />
<script src="/js/jquery-1.3.2.min.js" type="text/javascript"></script>
<script src="/js/grid.locale-en.js" type="text/javascript"></script>
<script src="/js/jquery.jqGrid.min.js" type="text/javascript"></script>
</head>

<body>

<table id="myTable"></table>
<input type="button" value="Delete Row" onclick="deleteRow();" /><br />
<input type="button" value="Get Row IDs" onclick="getRowIDs();" /><br />
<input type="button" value="Move up" onclick="move('up');" /><br />
<input type="button" value="Move down" onclick="move('down');" /><br />
<input type="button" value="Get Current Row" onclick="getCurrentRow();" />

<script type="text/javascript">
 var $table = $('#myTable');
 $(document).ready(function(){
 $table.jqGrid({
 datatype : 'local',
 width    : 300,
 height   : 250,
 colNames : ['Rank', 'ID', 'Product Description'],
 colModel : [
 { name: 'id', index: 'id', sorttype: 'int', sortable: false },
 { name: 'productID', index: 'productID', sortable: false },
 { name: 'productTitle', index: 'productTitle', sortable: false }
 ],
 caption  : 'Top 10 Products'
 });
 var myData = [
 <cfloop from="1" to="10" index="n"><cfoutput>
 {id: '#n#', productID: '#n#', productTitle: 'A test product #n#'}
 <cfif n lt 10>,</cfif>
 </cfoutput></cfloop>
 ] 
 for(var i = 0; i < myData.length; i++){
 $table.jqGrid('addRowData', i + 1, myData[i]);
 }
 });
 function deleteRow(){
 var tableData = new Array();
 var ids = '';
 $table.delRowData($table.getGridParam('selrow'));
 ids = $table.getDataIDs();
 for(var i = 0; i < ids.length; i++){
 tableData[i] = $table.getRowData(ids[i]);
 tableData[i].id = i + 1;
 }
 $table.clearGridData(false);
 for(i = 0; i < tableData.length; i++){
 $table.addRowData(i + 1, tableData[i]);
 }
 }
 function move(direction){
 if($table.getGridParam('selrow')){
 var ids = $table.getDataIDs();
 var temp = 0;
 var currRow = ids[ $table.getGridParam('selrow') - 1 ];
 if(direction === 'up' && currRow > 1){
 var r1 = $table.getRowData(currRow-1);
 var r2 = $table.getRowData(currRow);
 $table.delRowData(currRow-1);
 $table.delRowData(currRow);
 temp = r1.id;
 r1.id = r2.id;
 r2.id = temp;
 $table.addRowData(r2.id, r2);
 $table.addRowData(r1.id, r1);
 }
 if(direction === 'down' && currRow < (ids.length)){
 var r1 = $table.getRowData(currRow);
 var r2 = $table.getRowData(parseInt(currRow)+1);
 $table.delRowData(currRow);
 $table.delRowData(parseInt(currRow)+1);
 temp = r1.id;
 r1.id = r2.id;
 r2.id = temp;
 $table.addRowData(r1.id, r1);
 $table.addRowData(r2.id, r2);
 }
 // Sort the table   
 $table.setGridParam({sortname:'id'}).trigger('reloadGrid');
 }
 }
 function dumpObject(obj){
 var dataString = '';
 for(var i in obj){
 dataString += i + ': ' + obj[i] + '\n';
 }
 alert(dataString);
 }
 function getRowIDs(){
 var ids = $table.getDataIDs();
 var dataString = '';
 for(var i = 0; i < ids.length; i++){
 dataString += 'postion: ' + i + ' ' + ids[i] + '\n';
 }
 alert(dataString);
 }
 function getCurrentRow(){
 var dataString = '';
 var ids = $table.getDataIDs();
 dataString += 'Selected Row: ' + $table.getGridParam('selrow') + '\nRow ID: ' + ids[$table.getGridParam('selrow') - 1];
 alert(dataString);
 }
</script>

</body>
</html>

Advertisements

About Robert Zehnder

Web application developer specializing in ColdFusion/Railo and Open Source development.

Posted on February 25, 2010, in jQuery and tagged . Bookmark the permalink. 9 Comments.

  1. Have you ever tried to do an initial data load using the ‘data’ parameter? I cannot get that to work. The grid box appears but it contains no data. Any guidance much appreciated. Thanks.

  2. Ok. Inserting a row in JqGrid is not an issue but the issue is that to verify the data key in inline grid (example date field/column must enter valid date or integer filed/column must enter with number instead of character) and insert into the array and save into the database.
    I hope you could me us the coding how to do that ?

    Thank you.

  3. show us the coding…typing mistake

  4. thanks alot.

  5. I don’t think the move code will work if you have IDs that are not identical to row numbers. You are using IDs as Row IDs

    var r1 = $table.getRowData(currRow-1);

    and then as indexes:

    currRow < (ids.length)

  6. how can i move rows up and down if they have grouping true in jqgrid?

  1. Pingback: 2010 in review « KISDigital Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: