Click here to Skip to main content
Click here to Skip to main content

GridView inline Master/Detail record display

By , 17 Feb 2006
 

Introduction

This code drop is part of a smash and grab series. If you're in a rush, you can just grab this code and insert it into your application, no understanding is required. When you have some time (ya, right) you may want to review the source code.

Background

I was presented with a project to convert an Access single-user application into a web based multi-user SQL Server application. The Access application had about 10 tables that needed to be managed through an Add/Edit/Delete interface. This table maintenance was to be done by a single individual, so concurrency issues would not be a problem. I decided that with some tweaking, the GridView could perform what needed to be done. Out of the box, the GridView will not do row inserts, nor will it provide DropDownLists where the data to be edited is really an ID representing a row in another table. There is another CodeProject article GridViewRedux, which will show you how to do that. You must read that article first or this article will make no sense.

This article will show you how to code inline detail records just below a selected master record - just like Access does. For this article, I have used tables in the Northwind database.

Using the code

Download the project, unzip it to somewhere on your hard disk, and then create a new web project from an existing folder. Build the project, and test drive it so that you can see what it does. There are a few key files:

  • GridViewHelper.js which does all the DHTML heavy lifting.
  • Master.aspx contains the master record GridView.
  • Details.aspx contains the detail records.

Please download the source files and follow along as I explain what you need to insert.

Master.aspx

Insert this code in the <head> section of the file:

<script src="GridViewHelper.js" type="text/javascript"></script>
<link href="GridViewHelper.css" rel="STYLESHEET" type="text/css" />
<link href="AppStyle.css" rel="STYLESHEET" type="text/css" />

Insert this code following the </form> element:

<script type="text/javascript">
    GridViewHelper.Init(document.all.GridView1, 0, 0);
    var ToolTips = new Array("", "??", "??", "??");
    GridViewHelper.AddToolTips(document.all.GridView1, ToolTips);
</script>
  • Since this is a master page and not a detail page (the code detects that it is not running in an IFRAME), the Init function resizes the width of the page to the required width so that no columns wrap. If you don't want this functionality, don't call Init in the master page. The other parameters are required but ignored.
  • The GridView control does not support tooltips on the column headers, so GridViewHelper has a method AddToolTips which takes a reference to the grid and an array of tooltips that it applies to the column headers. Change "??" to whatever you want.

Master.aspx.cs

Most of the code in here is just boiler plate, just cut and paste. Two lines of code are kind of interesting:

string RowID = Convert.ToString(
    System.Web.UI.DataBinder.Eval(e.Row.DataItem, "CategoryID"));
string Url = "Details.aspx?ID=" + RowID;

When you call Details.aspx, you must tell it which category the details are for. This is how you do it.

Details.aspx

Notice that the <body> has been modified. This is to force the details to "snug" up against the master record and offset to the right by 40 pixels to allow the details table to appear indented. Also, scrolling has been turned off. You can safely turn scrolling off because the master page has been widened. Again, this is to "snug" up the detail records:

<body  leftmargin="40" topmargin="0" scroll="no">

Insert this code in the <head> section of the file:

<script src="GridViewHelper.js" type="text/javascript"></script>
<link href="GridViewHelper.css" rel="STYLESHEET" type="text/css" />
<link href="AppStyle.css" rel="STYLESHEET" type="text/css" />

Notice that the <form> has been modified. More "snugging":

<form id="form1" runat="server"  style="overflow: hidden;">

Notice that the <div> has been modified. More "snugging":

<div style="overflow: hidden;">

And now the magic. Insert this code following the </form> element:

<script type="text/javascript">
   GridViewHelper.Init(document.all.GridView1, 
                        ExtraWidth=100, ExtraHeight=0);
   var ToolTips = new Array("", "Product name", 
                  "Supplier", "Quantity per unit", 
                  "Unit price", "Units on order", 
                  "Reorder level", "Discontinued");
   GridViewHelper.AddToolTips(document.all.GridView1, ToolTips);
</script>

This causes the IFRAME, where the details are placed in, to be only as big as necessary. The ultimate "snugging". Notice the ExtraWidth=100, ExtraHeight=0 parameters above. When scroll in the <body> is set to no, you have nothing to do as these parameter values should suffice. If you set scroll="yes", then scroll bars may appear and you have to make room for them. This is where you experiment with changing the ExtraWidth/ExtraHeight parameters to larger numbers so that the detail records look correct (as few scroll bars as necessary). You never need a vertical scroll bar because the code sizes to the correct height. If you change ExtraHeight=25, you should have enough room for a horizontal scroll bar without the need for a vertical scroll bar.

Take a look at the DataSource lines:

SelectCommand="SELECT '0' as [ProductID], '' as [ProductName], 
    '' as [CompanyName], '0' as SupplierID, '0' as [QuantityPerUnit], 
    '0.00' as [UnitPrice], '0' as [UnitsInStock], '0' as [UnitsOnOrder], 
    '0' as [ReorderLevel], '0' as [Discontinued] 
UNION SELECT [ProductID], [ProductName], Suppliers.CompanyName, 
    Suppliers.SupplierID, [QuantityPerUnit], 
    convert(varchar(20), [UnitPrice], 0) as [UnitPrice], 
    [UnitsInStock], [UnitsOnOrder], [ReorderLevel], [Discontinued] 
FROM [Products] 
left join Suppliers on Suppliers.Supplierid=Products.SupplierID 
WHERE ([CategoryID] = @CategoryID) 
ORDER BY [ProductName]

Notice that the SELECT statement is expecting a QueryString parameter to insert into the WHERE clause. If you click on the Smart Tag for the DataSource, and select Configure Datasource, and then click Next once, you will see a WHERE button. Click on this to see how this clause was created. Also notice that I have converted the UnitPrice to a string so that it will only display two decimal places.

Take a look at the DataSource lines:

InsertCommand="INSERT INTO [Products] ([ProductName], 
     [SupplierID], [CategoryID], [QuantityPerUnit], [UnitPrice], 
     [UnitsInStock], [UnitsOnOrder], [ReorderLevel], [Discontinued]) 
     VALUES (@ProductName, @SupplierID, @CategoryID, 
        @QuantityPerUnit, convert(money,@UnitPrice), 
        @UnitsInStock, @UnitsOnOrder, @ReorderLevel, @Discontinued)

I had to convert the field back to money so the insertion would not fail with a "conversion from varchar to money error".

Details.aspx.cs

Most of the code in here is just boiler plate, just cut and paste. There is really only one trick in here and that has to do with inserting new records:

p = new System.Data.SqlClient.SqlParameter(
                "@CategoryID", Request.QueryString["ID"]);
c.Parameters.Add(p);

The insert requires a CategoryID and you can get it from the QueryString.

Points of interest

An interesting side effect of this technique is that detail records can have their own detail records ad infinitum. When you expand a detail block the first time, a request to the server is made to populate it. If you collapse the details block, the block is just hidden, so that the next time you request for expansion, there is no server hit, the block is just made visible again.

Notice: No AJAX was maimed or killed in the creation of this article. In fact, the newest kid on the block wasn't even required. I've got nothing against AJAX (in fact some of my friends use AJAX), but it's got its time and place (probably in my next project ;-).

Smash and Grab / Redux series

I have recently started two series of articles here at CodeProject. Smash and Grab is intended as a series of short articles on one specific code technique. Redux is intended as a series of longer articles which attempt to reduce a complicated topic (like GridView) into its basic constituent parts and show that once you have all the information, it isn't really that hard after all. To find Smash and Grab articles, search for the keyword SmashGrab. To find Redux articles, search for the keyword Redux. I welcome any contributions to either series, but please follow the guidelines when submitting articles to either.

Conclusions

Pretty easy, eh! (I'm Canadian). If you have the time, take a look at the source, there is some cool DHTML going on.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Gary Dryden
Software Developer (Senior)
Canada Canada
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5membertasgr20 Dec '12 - 8:20 
QuestionVB Version Available?memberEd Aymami9 Nov '12 - 11:55 
AnswerRe: VB Version Available?memberGary Dryden10 Nov '12 - 6:14 
GeneralMy vote of 5memberwmahendra17 Oct '12 - 19:59 
Generalthank you for your codemembernoppasak3 May '12 - 23:03 
QuestionFilter on Master.aspx [modified]memberSim_Card13 Apr '12 - 4:36 
AnswerRe: Filter on Master.aspxmemberGary Dryden13 Apr '12 - 4:58 
QuestionCan't get the details to displaymembercengentech30 Nov '11 - 4:31 
AnswerRe: Can't get the details to displaygroupMember 37466812 Feb '12 - 23:28 
GeneralMy vote of 5memberMember 808657918 Jul '11 - 23:41 
GeneralBrower Compatible IssuememberHaridass28 May '11 - 3:11 
GeneralRespect!memberMember 796127127 May '11 - 22:22 
GeneralMaster DetailmemberRELGERT27 May '11 - 6:02 
GeneralErro subgridmemberTiago Burahem15 Mar '11 - 13:01 
GeneralNew Edit (GridView inline Master/Detail record display)memberchitmm17 Dec '10 - 15:31 
GeneralCross Browser CompatiblememberBostonPopeye15 Dec '10 - 1:38 
GeneralErrormemberMember 377941314 Nov '10 - 19:55 
GeneralMy vote of 3memberjavad200930 Aug '10 - 20:56 
GeneralSIMPLE, EASY, The BestmemberIra Singh26 Aug '10 - 10:13 
GeneralCollapse All & Expand Allmembermenuely18 Apr '10 - 20:37 
Question3rd LayermemberRomeroBaco7 Apr '10 - 3:46 
GeneralRe: 3rd LayermemberVivsRane7 Apr '10 - 21:24 
AnswerRe: 3rd LayermemberVivsRane8 Apr '10 - 1:49 
GeneralRe: 3rd LayermemberRomeroBaco9 Apr '10 - 10:29 
GeneralRe: 3rd LayermemberRomeroBaco13 Apr '10 - 3:45 
GeneralRe: 3rd LayermemberVivsRane15 Apr '10 - 18:29 
QuestionRe: 3rd Layermembergatohsr2 Jun '11 - 7:59 
GeneralThank you.membertsreepallavi6 Apr '10 - 5:22 
GeneralHelp with Masterpage [modified]memberMember 43337655 Apr '10 - 9:00 
GeneralRe: Help with MasterpagememberMember 43337655 Apr '10 - 13:35 
AnswerRe: Help with MasterpagememberVivsRane7 Apr '10 - 21:23 
GeneralRe: Help with MasterpagememberTheoWillemse19 Jul '11 - 5:00 
GeneralRe: Help with MasterpagememberMember 43337656 Apr '10 - 16:04 
GeneralReadOnly GridsmemberJAGUARSOFT23 Mar '10 - 5:23 
GeneralRe: ReadOnly GridsmemberGary Dryden23 Mar '10 - 5:55 
GeneralRe: ReadOnly GridsmemberJAGUARSOFT24 Mar '10 - 1:49 
GeneralRe: ReadOnly GridsmemberGary Dryden24 Mar '10 - 1:58 
GeneralRe: ReadOnly Gridsmemberarfakyol22 Dec '10 - 3:16 
Generalgood jobmemberArlen Navasartian27 Jan '10 - 12:52 
Generalworking with master pagesmemberjoekelly25 Dec '09 - 10:50 
GeneralRe: working with master pagesmemberkarm12315 Jun '10 - 4:11 
QuestionWhere is the FF fixed code?memberit-bergmann24 Oct '09 - 7:19 
GeneralThis is Perfect man.....memberMember 214174621 Sep '09 - 21:25 
GeneralDoes not work in FireFoxmemberPratiksha Saxena18 Sep '09 - 1:59 
GeneralCode doesnt work in firefoxmemberdefineconst22 Jun '09 - 22:35 
GeneralFantastic ArticlememberM_Menon9 Jun '09 - 2:28 
Questionauto resize the mid layer subgrid. [modified]memberbinchentx1 Jun '09 - 14:01 
Questiongreat articlememberErnandes Silva18 May '09 - 17:59 
QuestionHow to expand all details by defaultmembershafie25 Mar '09 - 20:58 
GeneralRuntime Errormemberjct@maf3 Mar '09 - 12:43 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 18 Feb 2006
Article Copyright 2006 by Gary Dryden
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid