Chapter 8. Accessing Individual Elements in a Grid

Contents

8.1 Grid.Display vs. Grid.Display(False)

In all the code samples we have seen so far, we call Grid.Display to display a grid. The Display method internally calls Response.Write to send dynamically generated HTML code to the client browser. The Display method accepts an optional Boolean parameter which is set to True by default. If False is passed, AspGrid is switched to a "silent" mode:

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:

Grid.Display( False )

The next line displays the <TABLE> tag for our grid with all its attributes:

Response.Write Grid.Output.TableTag

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.

Response.Write Grid.Output.CaptionTag

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:

Set HRow = Grid.Output.HeaderRow

Then next line simply displays a <TR> tag:

Response.Write HRow.TR

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.

For Each Block in HRow.Blocks
  Response.Write Block.Value
Next

The following line simply displays </TR>:

Response.Write HRow.CloseTR

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:

For Each Row in Grid.Output.Rows

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.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

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):

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

Finally, we display the closing </TABLE> tag:

Response.Write Grid.Output.CloseTableTag

8.2 Using Grid.Output to Change Grid Appearance

Needless to say, there is no reason to use the Display(False)/Grid.Output-based approach just described if all you want is display a grid in its default form. However, if you do want to change the default appearance of your grid, there is no better way to do it.

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.

' Generate grid without displaying it
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

In the code above, we re-use the underlying ADO connection object, returned by Grid.Connection, to compute the salary total by executing the SQL statement select sum(salary) from employees. We then apply numeric formatting to the result of this query via the ApplyFormat helper method of the Column object. This method uses the formatting options specified by the FormatNumeric method earlier in the code.

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.

' Display Header
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.

' 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

    ' 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.

' Display "Total" Row
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.

' 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

  If Block.Index = 1 Then
    Response.Write "<TD>&nbsp;</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.

8.3 Painting a Grid in a Chessboard Manner

The last sample for this chapter, http://localhost/aspgrid/08_elements/display_chess.asp, paints a grid in a chessboard-like manner. We leave the code analysis of this sample to the reader as an exercise.
Using AspGrid in Frames Displaying All Records in Edit Mode