<asp:Button> Control
Server scripts are activated by events surrounding the Web page. The usual way to
call these scripts is through event handlers attached to controls. The
<asp:Button> control is the most common method to activate scripts. It displays
a clickable button that calls a subprogram or performs submission of the form on which it is
contained. The general format for this control is shown below.
Figure 5-1. General format for <asp:Button> control.
An id is not required unless the button's identity is referenced
by the called subprogram. The Text attribute provides the label
for the button. The OnClick event handler identifies a subprogram
to run when the button is clicked. The OnCommand,
CommandName, and CommandArgument properties call a
subprogram to pass along data or control information needed to perform processing.
Clicking a button performs a post-back operation. The page is reloaded, the
Page_Load subprogram, if coded, is run, followed by the subprogram named in the
OnClick event handler. Normally, post-back is to the same page.
However, a different page, named in the PostBackUrl property
can be called.
Calling a Subprogram
Normally a button's purpose is to call a subprogram by supplying the subprogram's name in an
OnClick event handler coded in the button. The following button operates
in this fashion. The called subprogram simply assigns a text string to an accompanying Label control.
Figure 5-2. Using a button to call a subprogram.
<SCRIPT Runat="Server">
Sub Button_Click (Src As Object, Args As EventArgs)
Message.Text = "The Button_Click subprogram was run."
End Sub
</SCRIPT>
<form Runat="Server">
<asp:Button Text="Call Button_Click" OnClick="Button_Click" Runat="Server"/>
<asp:Label id="Message" Runat="Server"/>
</form>
Listing 5-1. Coding a Button control.
Recall that a subprogram called by a button has the special signature (source
As Object, arguments As EventArgs). Programmer-supplied names are
provided for the source and arguments
variables in the argument list. These tutorials use the names
(Src As Object, Args As EventArgs); other identifiers
can be used. It is common to see the names "sender" and
"e" used for the two arguments: (sender As Object, e As EventArgs).
The source argument identifies the button that is clicked to
call the subprogram; arguments refer to any supporting data items
passed to the subprogram. In the case of a normal subprogram call, neither
source nor arguments comes into play. If, however,
the subprogram needs to refer to the clicked button, say to style it as visual indication that
it was clicked, then the source argument is used. In the following
example, a button has its colors and label changed to indicate it has been clicked.
Figure 5-3. Scripting a button style.
<%@ Import Namespace="System.Drawing" %>
<SCRIPT Runat="Server">
Sub Button_Click (Src As Object, Args As EventArgs)
Src.BackColor = Color.FromName("#FF0000")
Src.ForeColor = Color.FromName("#FFFFFF")
Src.Font.Size = FontUnit.Parse("11pt")
Src.Text = "I've been clicked!"
Message.Text = "The button '" & Src.id & "' was clicked."
End Sub
</SCRIPT>
<form Runat="Server">
<asp:Button id="MyButton" Text="Click Me" Runat="Server"
OnClick="Button_Click"/>
<asp:Label id="Message" Runat="Server"/>
</form>
Listing 5-2. Code to script button styling.
The source argument (Src in this
example) is the reference used to set server style properties of the button along with
its Text property. The id property of the
button (Src.id) is used in a message produced for the output Label.
Note that it is not necessary to assign the button an id. The
Src reference identifies the button whether explicitly identified
or not.
Scripting Command Buttons
A Button can be configured as a command button to pass control information to a subprogram
so that a single script can service multiple buttons and take appropriate action for
the particular button that is clicked. Buttons used in this way are coded with
OnCommand (rather than OnClick) event handlers. They include
CommandName and CommandArgument properties to
supply processing control information to the subprogram.
A subprogram called with OnCommand has a different signature from
one called with OnClick. Rather than EventArgs,
the argument list uses CommandEventArgs. It is through this argument
that the passed CommandName and CommandArgument
values are received.
The following example demonstates a subprogram called by a command button. The subprogram
reports values associated with the arguments passed by the button.
Figure 5-4. Using a command button to call a subprogram.
<SCRIPT Runat="Server">
Sub Report_Arguments (Src As Object, Args As CommandEventArgs)
PassedValues.Text = "<b>Src.id</b> = " & Src.id & "<br/>"
PassedValues.Text &= "<b>Args.CommandName</b>= " & _
Args.CommandName & "<br/>"
PassedValues.Text &= "<b>Args.CommandArgument</b>= " & _
Args.CommandArgument & "<br/>"
End Sub
</SCRIPT>
<form Runat="Server">
<asp:Button id="MyButton" Runat="Server"
Text="Report Arguments"
OnCommand="Report_Arguments"
CommandName="Do Something"
CommandArgument="With This Value"/>
<p><asp:Label id="PassedValues" Runat="Server"/></p>
</form>
Listing 5-3. Code to script a command button.
When the button is clicked, subprogram Report_Arguments is called.
Because the subprogram is called through an OnCommand event handler, the
button also sends its CommandName and, if present,
CommandArgument values to the subprogram.
The subprogram identifies the clicked button through its source
argument. The subprogram also receives through its arguments list
any CommandName and CommandArgument values that
are passed. In this example, Args.CommandName and
Args.CommandArgument give these values. Both are programmer-supplied values to pass processing
control information to the subprogram; they have no intrinsic values that are meaningful to the
subprogram.
The main reason for using an OnCommand event handler is to be able to
differentiate between multiple buttons calling the same subprogram. This capability is illustrated
by the following two buttons which call the same subprogram. Here, different buttons produce
different reports on their passed arguments.
Figure 5-5. Using command buttons to call a subprogram.
<SCRIPT Runat="Server">
Sub Report_Arguments (Src As Object, Args As CommandEventArgs)
PassedValues.Text = "<b>Src.id</b> = " & Src.id & "<br/>"
PassedValues.Text &= "<b>Args.CommandName</b>= " & _
Args.CommandName & "<br/>"
PassedValues.Text &= "<b>Args.CommandArgument</b>= " & _
Args.CommandArgument & "<br/>"
End Sub
</SCRIPT>
<form Runat="Server">
<asp:Button id="FirstButton" Runat="Server"
Text="Report Arguments"
OnCommand="Report_Arguments"
CommandName="Do This"
CommandArgument="With This Value"/>
<asp:Button id="SecondButton" Runat="Server"
Text="Report Arguments"
OnCommand="Report_Arguments"
CommandName="Do That"
CommandArgument="With That Value"/>
<p><asp:Label id="PassedValues" Runat="Server"/></p>
</form>
Listing 5-4. Code to script a pair of command buttons.
As you can see, there are three different ways to distinguish buttons from one another. They
can be differentiated by their id values; they can be differentiated
by their CommandName values; they can be differentiated by their
CommandArgument values. A subprogram can use any combination
of these passed values to differentiate processing requests.
Coding Choices
It is often not necessary to supply all three arguments to determine which processing option
is carried out by a subprogram. If, for instance, it is only a matter of choosing either of two
processing tasks requested by two different buttons, then the buttons' ids
are sufficient information for the subprogram to make the choice. It is not necessary to
supply CommandName or CommandArgument values.
The following subprogram is coded to distinguish between two buttons in order to take two
processing routes.
<SCRIPT Runat="Server">
Sub Do_Processing (Src As Object, Args As CommandEventArgs)
If Src.id = "FirstButton" Then
...do this processing
End If
If Src.id = "SecondButton" Then
...do this processing
End If
End Sub
</SCRIPT>
<form Runat="Server">
<asp:Button id="FirstButton" OnCommand="Do_Processing" Runat="Server"/>
<asp:Button id="SecondButton" OnCommand="Do_Processing" Runat="Server"/>
</form>
Listing 5-5. Referencing a source object of a subprogram call.
An alternative to the above coding is to supply CommandNames instead
of id values to distinguish processing choices. One reason for doing
this would be to make more explicit the processing choices represented by the buttons.
<SCRIPT Runat="Server">
Sub Do_Processing (Src As Object, Args As CommandEventArgs)
If Args.CommandName = "Process1" Then
...do this processing
End If
If Args.CommandName = "Process2" Then
...do this processing
End If
End Sub
</SCRIPT>
<form Runat="Server">
<asp:Button OnCommand="Do_Processing" CommandName="Process1" Runat="Server"/>
<asp:Button OnCommand="Do_Processing" CommandName="Process2" Runat="Server"/>
</form>
Listing 5-6. Using a CommandName to determine processing choices.
A second and more common reason for using CommandNames is to pass
along data values that are involved in the processing. In the following example, two buttons
supply the same subprogram with different data values to be involved in the same processing.
<SCRIPT Runat="Server">
Sub Do_Processing (Src As Object, Args As CommandEventArgs)
...do processing with Args.CommandName '-- with "Data1" or "Data2"
End Sub
</SCRIPT>
<form Runat="Server">
<asp:Button OnCommand="Do_Processing" CommandName="Data1" Runat="Server"/>
<asp:Button OnCommand="Do_Processing" CommandName="Data2" Runat="Server"/>
</form>
Listing 5-7. Using a CommandName to supply different data values.
If a subprogram offers additional processing choices, then both CommandName
and CommandArgument properties might be needed to isolate these
choices. In the following example, four buttons call the same subprogram requesting different
sorting actions on different data fields.
<SCRIPT Runat="Server">
Sub Do_Sorting (Src As Object, Args As CommandEventArgs)
If Args.CommandName = "Sort1" Then
If Args.CommandArgument = "SortUp" Then
...sort field 1 ascending
End If
End If
If Args.CommandName = "Sort1" Then
If Args.CommandArgument = "SortDown" Then
...sort field 1 descending
End If
End If
If Args.CommandName = "Sort2" Then
If Args.CommandArgument = "SortUp" Then
...sort field 2 ascending
End If
End If
If Args.CommandName = "Sort2" Then
If Args.CommandArgument = "SortDown" Then
...sort field 2 descending
End If
End If
End Sub
</SCRIPT>
<form Runat="Server">
<asp:Button Text="Sort 1 Ascending" Runat="Server"
OnCommand="Do_Sorting"
CommandName="Sort1"
CommandArgument="SortUp"/>
<asp:Button Text="Sort 1 Descending" Runat="Server"
OnCommand="Do_Sorting"
CommandName="Sort1"
CommandArgument="SortDown"/>
<asp:Button Text="Sort 2 Ascending" Runat="Server"
OnCommand="Do_Sorting"
CommandName="Sort2"
CommandArgument="SortUp"/>
<asp:Button Text="Sort 2 Descending" Runat="Server"
OnCommand="Do_Sorting"
CommandName="Sort2"
CommandArgument="SortDown"/>
</form>
Listing 5-8. Referencing a passed CommandArgument in a subprogram call.
For most processing requirements, it is usually not necessary to include these additional levels
of button differentiation. Differering id and/or
CommandName arguments are usually sufficient. If a subprogram requires an additional
CommandArgument to differentiate choices, then you might consider
whether the single subprogram is trying to do too much.
Using Buttons for Database Display
The following example is an illustration of the use of command buttons. All buttons call the
same subprogram to select display of book types from the BooksDB.mdb
database. The subprogram issues differently composed SQL statements to select different recordsets
for display in a GridView. The different SQL statements depend on the different
CommandName arguments passed by the buttons. This application uses an AccessDataSource to
connect to the database and a basic GridView to display results.
Figure 5-6. Using command buttons to issue SQL statements for book displays.
Script and control coding for this output is shown below. Notice that the buttons have
CommandName values indicating the BookType
field from the database to be used for selecting subsets of records.
<SCRIPT Runat="Server">
Sub Show_Books (Src As Object, Args As CommandEventArgs)
Dim SQLString As String
SQLString = "SELECT BookID, BookTitle, BookPrice FROM Books " & _
"WHERE BookType = '" & Args.CommandName & "'"
BookSource.SelectCommand = SQLString
End Sub
</SCRIPT>
<form Runat="Server">
<h3>View Book Types</h3>
<asp:Button Runat="Server"
Text="Database"
OnCommand="Show_Books"
CommandName="Database"
Width="80"/>
<asp:Button Runat="Server"
Text="Graphics"
OnCommand="Show_Books"
CommandName="Graphics"
Width="80"/>
<asp:Button Runat="Server"
Text="Hardware"
OnCommand="Show_Books"
CommandName="Hardware"
Width="80"/><br/>
<asp:Button Runat="Server"
Text="Software"
OnCommand="Show_Books"
CommandName="Software"
Width="80"/>
<asp:Button Runat="Server"
Text="Systems"
OnCommand="Show_Books"
CommandName="Systems"
Width="80"/>
<asp:Button Runat="Server"
Text="Web"
OnCommand="Show_Books"
CommandName="Web"
Width="80"/>
<asp:AccessDataSource id="BookSource" Runat="Server"
DataFile="../Databases/BooksDB.mdb"
SelectCommand="SELECT BookID, BookTitle, BookPrice FROM Books
WHERE BookType = 'Database'"/>
<p><asp:GridView DataSourceID="BookSource" Runat="Server"/></p>
</form>
Listing 5-9. Code to issue SQL command depending on CommandName of clicked button.
The AccessDataSource is originally coded with a SelectCommand to retrieve
a subset of records for initial GridView display. Subsequently, the GridView displays other subsets
of records corresponding with button clicks.
BookType values are received by subprogram
Show_Books through the CommandName property of its
CommandEventArgs argument (Args.CommandName).
These command names, which are also the BookType values appearing in the
database, are concatenated within a SELECT statement to select records
with these BookType values. For instance, if the first button is clicked
(CommandName="Database"), the following SQLString
value is produced.
SQLString = "SELECT BookID, BookTitle, BookPrice FROM Books " & _
"WHERE BookType = '" & Args.CommandName & "'"
-- becomes --
SELECT BookID, BookTitle, BookPrice FROM Books WHERE BookType = 'Database'
Listing 5-10. SQL statement produced by clicking a button.
When this SQLString variable is script-assigned to the
AccessDataSource's SelectCommand property, the data source is
immediately bound to the GridView to display these selected books.
Posting to a Different Page
Normally, a button click posts back to the same page on which the button appears. This is
the default behavior of the button's OnClick event handler. You can,
instead, post to a different page and still be able to access controls on the original page.
Posting to a different page takes place through the button's PostBackUrl
property. This property gives the URL of the page to which to post.
In the following example, a page contains two controls, a Button and a Label. The button
includes the PostBackUrl property to post to page
PostPage.aspx located in the same directory. When PostPage.aspx
opens, it accesses the button id and label Text
from the previous (posting) page.
Using PostBackUrl
Button:
Label: Text value to post
Figure 5-7. Posting to a different page.
Code for the posting page is shown below with a Button containing the
PostBackUrl property and a Label containing a text string for posting to
PostPage.aspx.
<h4>Using PostBackUrl</h4>
Button: <asp:Button id="PostingButton" Text="PostPage.aspx" Runat="Server"
PostBackUrl="PostPage.aspx"/><br/><br/>
Label: <asp:Label id="PostedValue" Text="Text value to post" Runat="Server"
BorderStyle="Ridge" Style="padding-left:10px; padding-right:10px"/>
Listing 5-11. Code to post to a different page.
The PostBackUrl page, PostPage.aspx,
includes a script to locate the Button and Label controls on the posting page and to report
their id and Text values, respectively.
<SCRIPT Runat="Server">
Sub Page_Load
Dim FoundButton As Button
FoundButton = PreviousPage.FindControl("PostingButton")
PostButton.Text = FoundButton.id
Dim FoundLabel As Label
FoundLabel = PreviousPage.FindControl("PostedValue")
PostValue.Text = FoundLabel.Text
End Sub
</SCRIPT>
<form Runat="Server">
<h3>This is PostPage.aspx</h3>
<p>The button with the id
"<asp:Label id="PostButton" Font-Bold="True" Runat="Server"/>"
posted the text value
"<asp:Label id="PostValue" Font-Bold="True" Runat="Server"/>"
from the previous page.
<p><a href="PostingPage.aspx">Return</a></p>
</form>
Listing 5-12. Code to retrieve and displays values from posting page.
The FindControl() Method
The page to which a posting is made through the PostBackUrl property
of a button does not have direct access to controls on the posting page. That is, a
script on PostPage.aspx cannot directly reference the Button or the
Label on the posting page. It cannot, as can be done on a page posted back to itself, use
PostingButton.id or PostedValue.Text to
directly retrieve the id and Text properties
of these controls on the posting page.
The technique that must be used involves first finding the controls of interest on the
previous page and then referencing properties of these found controls. The posting page
is identified through the PreviousPage property; controls on
this page are located with its FindControl() method. The
FindControl() method of PreviousPage has
the general formats shown in Figure 5-8.
Figure 5-8. General format to locate a control on a posting page.
First, an object of the type to be located is declared. When locating a Button, for instance,
the object is declared as type Button; when locating a Label, the object
is declared as type Label. Any ASP.NET control type can be declared
to match the control type to be located.
Second, this declared object is assigned the control of interest from the
PreviousPage using the FindControl("id") method to
identify the control through its id. Once "found" and assigned to
the locally declared object, properties of a control appearing on the posting page can be
referenced through this local object. This technique is used in the Page_Load
subprogram on the PostPage.aspx page.
Sub Page_Load
Dim FoundButton As Button
FoundButton = PreviousPage.FindControl("PostingButton")
PostButton.Text = FoundButton.id
Dim FoundLabel As Label
FoundLabel = PreviousPage.FindControl("PostedValue")
PostValue.Text = FoundLabel.Text
End Sub
Listing 5-13. Script to locate and report control properties from posting page.
Object reference FoundButton (any programmer-supplied name can be used)
is declared as a Button object. It is then assigned the Button with
id="PostingButton" located on the PreviousPage
(posting page). Likewise for the Label. Object reference FoundLabel
is declared as a Label object. The Label with
id="PostedValue" on the PreviousPage is
assigned to this script object. Thereafter, properties associated with these controls appearing
on the posting page are accessible through their surrogate references on the current page. In this
example, FoundButton.id accesses the id
property of the Button on the posting page; FoundLabel.Text accesses
the Text property of the Label on the posting page. These two values
are displayed in Labels appearing on the posted page.
You need to become familiar with the FindControl() method. It has
many uses under ASP.NET besides locating controls on pages which issue
PostBackUrls. It is routinely used to locate controls embedded inside other controls
on the same page.