Chapter 8. Accessing Individual Elements in a Grid
Contents
8.1 Grid.Display vs. Grid.Display(False)
This call is identical to Grid.Display except that it does not send any information directly to the browser. Instead it generates a collection of objects representing individual elements of a grid. This collection is accessible via the property Grid.Output.
The code sample
displays the ubiquitous Employees table by calling Display(False), then iterating through the objects of the Grid.Output collection and displaying individual grid elements. The code shown below has exactly the same effect as calling Grid.Display. For the sake of brevity, the formatting portion of the code is omitted.
... ' Formatting code omitted
' Generate grid without displaying it
Grid.Display( False )
' Display grid manually
Response.Write Grid.Output.TableTag
Response.Write Grid.Output.CaptionTag
' if appropriate
' Display Header
Set HRow = Grid.Output.HeaderRow
Response.Write HRow.TR
For Each Block in HRow.Blocks
Response.Write Block.Value
Next
Response.Write HRow.CloseTR
' Display Body
For Each Row in Grid.Output.Rows
Response.Write Row.Form
Response.Write Row.TR
For Each Block in Row.Blocks
Response.Write Block.TD
Response.Write Block.Font
Response.Write Block.Value
Response.Write Block.CloseFont
Response.Write Block.CloseTD
Next
Response.Write Row.CloseTR
Response.Write Row.CloseForm
Next
' Display Footer
Set FRow = Grid.Output.FooterRow
Response.Write FRow.Form
Response.Write FRow.TR
For Each Block in FRow.Blocks
Response.Write Block.TD
Response.Write Block.Value
Response.Write Block.CloseTD
Next
Response.Write FRow.CloseTR
Response.Write FRow.CloseForm
' Display </TABLE> tag
Response.Write Grid.Output.CloseTableTag
%>
Let's examine this code snippet line by line. The first line shown here generates the grid HTML but does not display it directly. Instead, it populates a collection of objects accessible from the read-only property Grid.Output:
The next line displays the <TABLE> tag for our grid with all its attributes:
The following line displays the <CAPTION>...</CAPTION> tags in case Grid.Table.Caption is specified. If a caption were not specified this line would have no effect.
The next line obtains a Row object that represents the header row of the grid (the one containing column captions and sort buttons). In general, a Row object represents a portion of a grid enclosed between <TR> and </TR> tags:
Then next line simply displays a <TR> tag:
The next three lines iterate through the Row.Blocks collection and display individual "blocks". A Block object represents a portion of a row enclosed between <TH> and </TH>, or <TD> and </TD>, tags. A header block may also encapsulate the <FORM> and </FORM> tags in case this column contains sort buttons.
Response.Write Block.Value
Next
The following line simply displays </TR>:
The next logical section of this code snippet is concerned with displaying the body of our grid. A grid body consists of several (0 or more) rows. Each individual row is represented by a Row object, and all the rows reside in the collection Output.Rows. The following line iterates through the Rows collection:
Displaying an individual body row involves the following steps:
- Display the opening <FORM> tag;
- Display the opening <TR> tag;
- Display all row blocks;
- Display the closing </TR> tag;
- Display the closing </FORM> tag.
Displaying an individual block inside a row, in turn, involves the following steps:
- Display the opening <TD> tag;
- Display the opening <FONT> tag;
- Display the cell value;
- Display the closing </FONT> tag;
- Display the closing </TD> tag;
The following lines display a row and all blocks inside it:
Response.Write Row.TR
For Each Block in Row.Blocks
Response.Write Block.TD
Response.Write Block.Font
Response.Write Block.Value
Response.Write Block.CloseFont
Response.Write Block.CloseTD
Next
Response.Write Row.CloseTR
Response.Write Row.CloseForm
You may have noticed that the Row object representing a body row provides greater granularity that the header Row object. Specifically, the Block objects that comprise a body row give you access to individual <TD> and <FONT> tags, as well as cell values, whereas header Blocks do not. This is due to the fact that you are far more likely to want to customize body cells that the header. For example, you may want to change a cell color/font depending on its value, or replace one cell value with another.
Displaying the footer section of a grid is very similar to displaying an individual row in a grid body except that there are no <FONT> tags involved (due to the fact that a footer contains no text, just buttons):
Response.Write FRow.Form
Response.Write FRow.TR
For Each Block in FRow.Blocks
Response.Write Block.TD
Response.Write Block.Value
Response.Write Block.CloseTD
Next
Response.Write FRow.CloseTR
Response.Write FRow.CloseForm
Finally, we display the closing </TABLE> tag:
8.2 Using Grid.Output to Change Grid Appearance
In our second code sample, http://localhost/aspgrid/08_elements/display_custom.asp, we add a new column to our Employees grid that shows row numbers. We also add a new row at the bottom that displays a total for the salary column:
The code for display_custom.asp is very similar to what we have just examined, but with a few additions. We will show those additions in bold face.
Grid.Display( False )
' Compute salary total by re-using the current connection
Set RecTotal = Grid.Connection.Execute _
("select sum(salary) from employees")
Total = RecTotal(0).Value
FormattedTotal = Grid.Cols("salary").ApplyFormat(Total)
' Initialize count by using RecordsSkipped property
Count = Grid.RecordsSkipped + 1
We also use the property RecordsSkipped to initialize a count variable. In this and previous examples we limit the number of rows displayed at a time to 3 by setting the property MaxRows. RecordsSkipped returns the current number of rows skipped by pagination. We use this value later in the code to display row numbers correctly in the new column.
Set HRow = Grid.Output.HeaderRow
Response.Write HRow.TR
For Each Block in HRow.Blocks
Response.Write Block.Value
' Display a # column after the first column
If Block.Index = 1 Then
Response.Write "<TH BGCOLOR=""#B0B0FF"">#</TH>"
End If
Next
Response.Write HRow.CloseTR
The Block object provides a read-only property, Index, that returns a 1-based order number of the block within a row. E.g. that left-side control button column has the index 1, the "Department" column has the index 2, etc. The code above adds a new column header, #, right after column 1.
For Each Row in Grid.Output.Rows
Response.Write Row.Form
Response.Write Row.TR
For Each Block in Row.Blocks
Response.Write Block.TD
Response.Write Block.Font
Response.Write Block.Value
Response.Write Block.CloseFont
Response.Write Block.CloseTD
' Display order number after the first column
If Block.Index = 1 Then
Response.Write "<TD>" & Count & "</TD>"
Count = Count + 1
End If
Next
Response.Write Row.CloseTR
Response.Write Row.CloseForm
Next
The code above adds a new column containing a row number after column 1, and increase the row count by one.
Response.Write _
"<TR><TD COLSPAN=4>Total:</TD><TD><FONT FACE=""Arial Narrow"">$" _
& FormattedTotal & "</FONT></TD><TD COLSPAN=4> </TD></TR>"
The line above adds a new row right after the last data row. This row displays the salary total value computed earlier.
Set FRow = Grid.Output.FooterRow
Response.Write FRow.Form
Response.Write FRow.TR
For Each Block in FRow.Blocks
Response.Write Block.TD
Response.Write Block.Value
Response.Write Block.CloseTD
If Block.Index = 1 Then
Response.Write "<TD> </TD>"
end If
Next
Response.Write FRow.CloseTR
Response.Write FRow.CloseForm
Finally the code above displays the grid footer and adds an extra (empty) column to it as well.