p2p.wrox.com Forums

p2p.wrox.com Forums (http://p2p.wrox.com/index.php)
-   ASP.NET 1.0 and 1.1 Basics (http://p2p.wrox.com/forumdisplay.php?f=60)
-   -   Determining Which Button Was Clicked (http://p2p.wrox.com/showthread.php?t=28940)

BrianWren May 4th, 2005 02:02 PM

Determining Which Button Was Clicked
 
Given:

   A VB.NET web application
   1 .aspx with:
        a submit button on it (a plain <input type="submit" name="btnSubmit" . . .>; [u]not</u> runat=server)
        an input called "TheBox"

   That one page is called Page1.aspx
   Page1.aspx is set as startup page
   At the browser, the <form>’s HTML is:
Code:

      <form name="Form1" id="Form1" method="post" action="Page1.aspx">


In a VB6 IIS application, clicking this button would put an item in Request.Form called "btnSubmit," whose value was the value of the face of the button.

I have used this frequently to assess which button has been clicked when the form has more than 1 button.

In my VB.NET app, the button is not in the form. The form has two items, the hidden __VIEWSTATE and the textbox.

If I have more than one submit button, how can I tell which was clicked?

(Clearly I can convert the buttons to run at the server, but I am trying to get a grasp of the machinery under asp+.)

planoie May 5th, 2005 04:46 AM

How do you expect to get a submit button to function if it's not in a/the form tag?

From my ASP experience I've come to two conclusions about how ASP.NET works:

1) I used to build postback forms in ASP. I did this with a big If block that check from the server variable "CONTENT_LENGTH" or something like that. That told me the length of the posted data. Any length and I was doing a postback. So then I did all my postback stuff which included testing for which submit button was clicked (if I had more than one). Which takes us to #2.

2) All Buttons that render as a submit (as well as image input types that function as submits) draw normally in ASP.NET. When the form is posted, only the clicked submit element is posted. This way you can check all the elements you know are on the page and see if they are in the posted Form() collection. The one that is is your clicked item.

All other postback events in ASP.NET are driven by the client function __doPostback. This functions by placing the click-side name of the control that is firing the postback into a hidden form element and forcing a form post. The server then reads that hidden form element value and figures out the server control that fired the postback.

I've utilized a few neat tricks with this feature. Often I'll need to fire a server-side postback event when some clientside event occurs, but I don't need a corresponding control on the page. So I'll put an asp:button on the page that is invisible (so I have a legitimate control in the page's control hierarchy). Then I use the page class method GetPostbackEventReference(cmdMyButton). This returns a string with the clientside call to the __doPostback function. So instead of a submit button on the page, I fire the postback with javascript based on whatever I need. The result is that I can write a handler for the hidden button's Click event.

-Peter

BrianWren May 5th, 2005 01:28 PM

Given the following:
Code:

<html>
    <body>
    <form method="post" action="Page1.aspx">
        <input type="text"  id="TheBox"    name="TheBox"    value="...">
        <br>
        <input type="submit" id="btnSubmit" name="btnSubmit" value="Cancel">
        &nbsp;&nbsp;
        <input type="submit" id="btnSubmit" name="btnSubmit" value="Save">
    </form>
    </body>
</html>

in VB IIS web classes the form element Request.Form("btnSubmit") would have the contents of the value property of the button that was clicked. The buttons are within the form block.

But with VB.NET, in an ASP.NET project, there does not appear to be anything in the collection of values that the form is holding for the clicked submit button.

With respect to (1) in your post, above, VB.NET has a value (IsPostback) which accomplishes in a variable/property that wich you describe.

It is true that only the specific form block with the clicked submit button gets sent to the inet server.

I believe that perhaps the functionality that you describe where you start “All other postback events in ASP.NET . . . ” is for buttons (submit or other) which at least specify runat="server", or are additionally “<asp:...” controls.

Where did you learn of this __doPostback function?
Do you know the name of that hidden form element?

This GetPostbackEventReference(): A user-defined function (such as one you wrote), or something that is part of the software from Microsoft?

planoie May 5th, 2005 03:24 PM

I guess I got confused by the line in your first post: "In my VB.NET app, the button is not in the form."

1) I have a login page with 2 textboxes (user, password), and a button. I debugged the page and looked at the resulting Request.Form collection. Here's what I got.
Request.Form.AllKeys(0): "__EVENTTARGET"
Request.Form.AllKeys(1): "__EVENTARGUMENT"
Request.Form.AllKeys(2): "__VIEWSTATE"
Request.Form.AllKeys(3): "txtUsername"
Request.Form.AllKeys(4): "txtPassword"
Request.Form.AllKeys(5): "cmdLogin"

Item 5 is the button. For the sake of argument, I added a second button "cmdTest" and repeated the process. The only difference was item 5:

Request.Form.AllKeys(5): "cmdTest"

So this behaves just like ASP, which makes sense because it's an HTTP behavior (vs. just .NET) to send the clicked submit button.

2) __doPostBack:
Look at the source code for a page that has some control (besides a button) that does a postback, such as a checkbox, radiobutton, DDL, etc. Even a link button has this, just look in the browser statusbar when you mouse over it.

Whenever you have a control that requires postback (ex. checkbox with autopostback=true) ASP.NET will write out script that contains the __doPostBack function.

function __doPostBack(eventTarget, eventArgument) {
    var theform;
    ...
    theform.__EVENTTARGET.value = eventTarget.split("$").join(":");
    theform.__EVENTARGUMENT.value = eventArgument;
    theform.submit();
}

That function references a couple other hidden fields in the form: __EVENTTARGET and __EVENTARGUMENT. This is what holds the target and argument for the postback call. For a postback call the client-side unique ID of the control initiating the postback is the target. Argument is optional.

3) GetPostBackEventReference:
From the msdn article: "Obtains a reference to a client-side script function that causes, when invoked, the server to post back to the page."

To get intellisense for this in Visual Studio: Tools-> Options-> Text Editor-> All Languages-> Uncheck "Hide Advanced Members". (There are a host of goodies that are hidden in VS by default.)

The reason you want to use this method is that (presumably) the __doPostBack method is generated by .NET so if you hard coded it you could get into trouble. Plus, you don't need to do anything special for it, just pass in the control for which you'd like the postback reference and let .NET create the piece of JS for you.

-Peter


All times are GMT -4. The time now is 01:52 PM.

Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.