
Clicking on the plus or minus icons beside each "parent" record reveals or hides the associated "child" records.
But this approach does have limitations: data in a subgrid cannot be sorted, or edited, and the alignment of the data in the columns is always "left". If you need more power than what this offers, then consider using a grid as a subgrid or, even, Master/Detail grids. But for a quick way to display details, follow the method described here.
The data described in the subgrid model must be mapped by either xmlReader or jsonReader. For xml data, the mapping would follow this example:
xmlReader : { root: "rows", row: "row", page: "rows>page", total: "rows>total", records : "rows>records", repeatitems: true, cell: "cell", id: "[id]", subgrid: {root: "rows", row: "row", repeatitems: true, cell: "cell"} }
and for json mapping, like the following:
jsonReader : { root: "rows", page: "page", total: "total", records: "records", repeatitems: true, cell: "cell", id: "id", subgrid: {root: "rows", repeatitems: true, cell: "cell"} }
The mapping rules are the same as those in the basic grid.
For more information see the discussion of xml and JSON in Data Types.
Continuing to use the example from the tutorial, let's suppose that there is a need to display the line items for each invoice in a subgrid. The Java script code should look like this.
<script type="text/javascript"> jQuery(document).ready(function(){ jQuery("#list").jqGrid({ url:'example.php', datatype: 'xml', colNames:['Inv No', 'Date', 'Amount', 'Tax', 'Total', 'Notes'], colModel :[ {name:'invid', index: 'invid', width: 55}, {name:'invdate', index: 'invdate', width: 90}, {name:'amount', index: 'amount', width: 80, align: 'right'}, {name:'tax', index: 'tax', width: 80, align: 'right'}, {name:'total', index: 'total', width: 80,align: 'right'}, {name:'note', index: 'note', width: 150, sortable: false} ], pager: jQuery('#pager'), rowNum:10, rowList:[10,20,30], sortname: 'id', sortorder: "desc", viewrecords: true, imgpath: 'themes/basic/images', caption: “My first grid, subGrid: true, subGridUrl : "subgrid.php", subGridModel [ { name: ['No', 'Item', 'Qty', 'Unit', 'Line Total'], width : [55, 200, 80, 80, 80], params: ['invdate'] } ] }); }); </script>
The next step is to configure the subgrid.php file. The example is in PHP and MySQL
<?php // get the id passed automatically to the request $id = $_GET['id']; // get the invoice data passed to this request via params array in //subGridModel. We do not use it here - this is only demostration $date_inv = $_GET['invdate']; // connect to the database $db = mysql_connect($dbhost, $dbuser, $dbpassword) or die("Connection Error: " . mysql_error()); mysql_select_db($database) or die("Error conecting to db."); // construct the query $SQL = "SELECT num, item, qty, unit FROM invlines WHERE id=".$id." ORDER BY item"; $result = mysql_query( $SQL ) or die("Couldn?t execute query.".mysql_error()); // set the header information if ( stristr($_SERVER["HTTP_ACCEPT"],"application/xhtml+xml") ) { header("Content-type: application/xhtml+xml;charset=utf-8"); } else { header("Content-type: text/xml;charset=utf-8"); } echo "<?xml version='1.0' encoding='utf-8'?>"; echo "<rows>"; // be sure to put text data in CDATA while($row = mysql_fetch_array($result,MYSQL_ASSOC)) { echo "<row>"; echo "<cell>". $row[num]."</cell>"; echo "<cell><![CDATA[". $row[item]."]]></cell>"; echo "<cell>". $row[qty]."</cell>"; echo "<cell>". $row[unit]."</cell>"; echo "<cell>". number_format($row[qty]*$row[unit],2,'.',' ')."</cell>"; echo "</row>"; } echo "</rows>"; ?>
After this, the grid will look like the example at the top of this page.
A subGrid can be enabled (or disabled) dynamically (to respond to changes in the data in the main grid, for example).
To disable a subgrid:
to enable a subgrid:$("#grid_id").hideCol('subgrid');
$("#grid_id").showCol('subgrid');