ASP 101 - Active Server Pages 101 - Web04
The Place ASP Developers Go!

Please visit our partners


Windows Technology Windows Technology
15 Seconds
4GuysFromRolla.com
ASP 101
ASP Wire
VB Forums
VB Wire
WinDrivers.com
internet.commerce internet.commerce
Partners & Affiliates














ASP 101 is an
internet.com site
ASP 101 is an internet.com site
IT
Developer
Internet News
Small Business
Personal Technology

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers

ASP 101 News Flash ASP 101 News Flash



 Top ASP 101 Stories Top ASP 101 Stories
What is ASP?
VBScript Classes: Part 1 of N
Migrating to ASP.NET

QUICK TIP:
Attach Files from Interdev to Email Messages Easily
Show All Tips >>
ASP 101 RSS Feed ASP 101 Updates


Building a Better Button Handler in ASP

by Jim Tonn - jmtonn (at) comcast (dot) net

If you've ever worked on an ASP page with a lot of submit buttons, you know that sometimes it can take some tricky coding to determine what button the user pressed when the page is posted to the server. The problem is that there are only two ways to identify a button with the Request object: by the value attribute (i.e., the text that appears inside the button), and by the name attribute. The former method is useful if you have several buttons with different text values, but you're stuck if you want to have two buttons with the same text. The latter method enables you to have multiple buttons with the same text, but you have to give each one a different name, which can be hard to do if you are generating an unknown number of buttons and can't hardcode the names at design time.


Button Processing using the Value Attribute
<%
' Returns the Value Attribute
Select Case Request.Form("buttonname")
   Case "One"
      Response.Write "Button one pressed"
   Case "Two"
      Response.Write "Button two pressed"
End Select
%>
<form name="form1" action="self.asp" method="POST">
   <input type="submit" name="buttonname" value="One"/>
   <input type="submit" name="buttonname" value="Two"/>
</form>


Button Processing using the Name Attribute
<%
If Request.Form("One") <> "" Then Response.Write "First button pressed"
If Request.Form("Two") <> "" Then Response.Write "Second button pressed"
%>
<form name="form1" action="self.asp" method="POST">
   <input type="submit" name="One" value="Button text"/>
   <input type="submit" name="Two" value="Button text"/>
</form>

Relying on the value attribute seems to be the most popular of the two methods, since most pages don't have more than one submit button with the same text. But consider this scenario: you are creating an HTML table based on a database, and you want to give the user the option to delete an entry via a delete button in each row of the table. How do you set up your table so it's easy to figure out which delete button the user pressed? You could use the second method from above, dynamically generating the name attributes based on some unique value from the database. Or you might end up doing something even more tricky using multiple forms and hidden fields.

The old solution to the multiple-delete-buttons problem
<%
'process form submission...
'(rsUserList contains contents of userList table)
Do While NOT rsUserList.EOF
   If Request.Form("cmdDelete" & rsUserList("userID")) = "Delete" Then
      Call DeleteUser(rsUserList("userID"))
      Response.Write "Bye, " & rsUserList("firstName") & "!"
   End If
   rsUserList.MoveNext
Loop
'draw form...
%>
<table>
   <%Do While NOT rsUserList.EOF%>
      <tr>
         <td><%=rsUserList("firstname") & " " & rsUserList("lastname")%></td>
         <td><input type="submit"
            name="cmdDelete<%=rsUserList("userID")%>"
            value="Delete"/></td>
      </tr>
      <%rsUserList.MoveNext
   Loop%>
</table>

What if you could specifiy an arbitrary number of parameters along with each button, so you could not only logically and easily determine which of your buttons was pressed, but you could also have additional information passed in a simple way? The ButtonHandler class allows you to embed extra data in the name attribute of a submit button, and access it easily after postback.

ButtonHandler.asp
<%
''
' A Button Handler is a utility object for working with buttons. It allows
' them to store more information than just a name by using a dot delimiter
' in the name attribute of the input tag.
'
' For example, you can create a series of buttons like this:
' <input type="submit" name="cmdDelete.23422341.9080" value="Add"/>
' <input type="submit" name="cmdDelete.89562331.1024" value="Add"/>
' <input type="submit" name="cmdDelete.99381200.7453" value="Add"/>
'
' In the above button, cmdDelete is the "base name," and the two numeric
' portions are "button parameters." Using a ButtonHandler, I can determine
' whether any button with a particular base name has been pressed, and
' extract the parameters.
'
' All routines in this class are functions, so that a consistent calling
' syntax can be used to access them.
'
Class ButtonHandler
   '' The form that this button handler works on (a Request.Form object).
   Private m_form
   '' Inspector for m_form.
   Public Property Get form()
      Set form = m_form
   End Property 'get form
   '' Mutator for m_form.
   Public Property Set form(p_form)
      Set m_form = p_form
   End Property 'set form
   ''
   ' Determines if any button with the specified base name was pressed
   ' on the form.
   ' Example:
   '   If bh.wasPressed("cmdAdd") Then Response.Write "User wants to add" 
   '
   ' @param strButtonBaseName the base name of a button being looked for.
   ' @return true if the button was pressed, false if not.
   '
   Public Function wasPressed(strButtonBaseName)
      Dim strField 'a key in the form
      wasPressed = false
      'make sure a form has been provided
      If NOT IsObject(m_form) Then
         'no form present in m_form
         Exit Function 'wasPressed will be false
      End If 'is a form loaded in m_form?
      For Each strField In m_form
         If Left(strField, Len(strButtonBaseName)) = strButtonBaseName Then
            wasPressed = true
            Exit Function 'no use sticking around
         End If 'if the button was present as a key in the form         
      Next 'strField
   End Function 'wasPressed
   ''
   ' Allows the caller to get a particular parameter that was specified in
   ' the button name attribute.
   ' Parameter numbers start at 1. 0 will return the base name.
   ' For example, if my button name was "cmdDelete.123441.true", then
   '    bh.requestParameter("cmdDelete", 0) returns "123441"
   '    bh.requestParameter("cmdDelete", 1) returns "true"
   '
   ' @param strButtonBaseName the base name of the button to look up.
   ' @param nParam            the number of the parameter to retrieve, where
   '                          0 is the base name and 1 is the first parameter.
   ' @return                  the value of the parameter requested, or "" if
   '                          the specified button/parameter does not exist.
   '
   Public Function requestParameter(strButtonBaseName, nParam)
      Dim strField      'a key in the form
      Dim strFoundField 'a key in the form that matches the requested base name
      Dim arrFoundField 'strFoundField, split up into an array around ".".
      strFoundField = ""
      For Each strField In m_form
         If Left(strField, Len(strButtonBaseName)) = strButtonBaseName Then
            strFoundField = strField
            'response.write "basename found"
            Exit For 'we found a matching button, no need to look further
         End If 'if the button was present as a key in the form
      Next 'strField
      ' At this point, if strFoundField is blank, then a matching button was
      ' not found: return blank.  If strFoundField is populated, then a
      ' matching button was found: look for the requested parameter.
      If strFoundField = "" Then
         requestParameter = ""
         Exit Function
      End If 'did we fail to find a matching button?
      'split the field string up around the "." delimiter
      arrFoundField = Split(strFoundField, ".")
      If nParam > UBound(arrFoundField) OR nParam < LBound(arrFoundField) Then
         'specified parameter does not exist
         requestParameter = ""
      Else 'i.e. specified parameter does exist
         requestParameter = arrFoundField(nParam)
      End If 'was the specified parameter in the valid range of parameters?
   End Function 'requestParameter
End Class 'ButtonHandler
%>

Let's take a look at the ButtonHandler in action.

ButtonTest.asp
<!-- #include file="ButtonHandler.asp" -->
<%
Dim bh
Set bh = New ButtonHandler
Set bh.form = Request.Form
If bh.wasPressed("quadrantOne")   Then Response.Write "quadrant one"
If bh.wasPressed("quadrantTwo")   Then Response.Write "quadrant two"
If bh.wasPressed("quadrantThree") Then Response.Write "quadrant three"
If bh.wasPressed("quadrantFour")  Then Response.Write "quadrant four"
%>
<form action="ButtonTest.asp" method="post">
   <table border="1" cellpadding="5">
      <tr>
         <td bgcolor="<%=bh.requestParameter("quadrantOne", 1)%>">
            <input type="submit" name="quadrantOne.red" value="Red"/>
            <input type="submit" name="quadrantOne.blue" value="Blue"/>
         </td>
         <td bgcolor="<%=bh.requestParameter("quadrantTwo", 1)%>">
            <input type="submit" name="quadrantTwo.red" value="Red"/>
            <input type="submit" name="quadrantTwo.blue" value="Blue"/>
         </td>
      </tr>
      <tr>
         <td bgcolor="<%=bh.requestParameter("quadrantThree", 1)%>">
            <input type="submit" name="quadrantThree.red" value="Red"/>
            <input type="submit" name="quadrantThree.blue" value="Blue"/>
         </td>
         <td bgcolor="<%=bh.requestParameter("quadrantFour", 1)%>">
            <input type="submit" name="quadrantFour.red" value="Red"/>
            <input type="submit" name="quadrantFour.blue" value="Blue"/>
         </td>
      </tr>
   </table>
</form>

Now that we've identified the basic functionality of the ButtonHandler, let's see how it performs in the user deletion scenario:

Multiple Delete Buttons the ButtonHandler Way
<!-- #include file="ButtonHandler.asp" -->
<%
Dim bh
Set bh = New ButtonHandler
Set bh.form = Request.Form
If bh.wasPressed("cmdDelete") Then
   Call DeleteUser(bh.requestParameter("cmdDelete", 1))
   Response.Write "Bye, " & bh.requestParameter("cmdDelete", 2) & "!"
End If
%>
<table>
   <%Do While NOT rsUserList.EOF%>
      <tr>
         <td><%=rsUserList("firstname")%> <%=rsUserList("lastname")%></td>
         <td><input type="submit"
            name="cmdDelete.<%=rsUserList("userID")%>.<%=rsUserList("firstname")%>"
            value="Delete"/></td>
      </tr>
      <%rsUserList.MoveNext
   Loop%>
</table>

It's not too much shorter, but it is more elegant. The ButtonHandler can be used on any page with buttons to make processing more intuitive, but is most effective when you need to pass a little more data than the basic button normally allows for. Try it on large forms, complex forms, and forms with a lot of repetition.

Download

You can download the accompanying source code for this article in zip file format from here: ButtonHandler.zip (2.2 KB).


Home |  News |  Samples |  Articles |  Lessons |  Resources |  Forum |  Links |  Search |  Feedback

Internet.com
The Network for Technology Professionals

Search:

About Internet.com

Legal Notices, Licensing, Permissions, Privacy Policy.
Advertise | Newsletters | E-mail Offers