Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
Markdown Monster - The Markdown Editor for Windows

Changing an HTML Form's Target with jQuery


:P
On this page:

This is a question that comes up quite frequently: I have a form with several submit or link buttons and one or more of the buttons needs to open a new Window. How do I get several buttons to all post to the right window?

If you're building ASP.NET forms you probably know that by default the Web Forms engine sends button clicks back to the server as a POST operation. A server form has a <form> tag which expands to this:

<form method="post" action="default.aspx" id="form1">

Now you CAN change the target of the form and point it to a different window or frame, but the problem with that is that it still affects ALL submissions of the current form. If you multiple buttons/links and they need to go to different target windows/frames you can't do it easily through the <form runat="server"> tag.

Although this discussion uses ASP.NET WebForms as an example, realistically this is a general HTML problem although likely more common in WebForms due to the single form metaphor it uses. In ASP.NET MVC for example you'd have more options by breaking out each button into separate forms with its own distinct target tag. However, even with that option it's not always possible to break up forms - for example if multiple targets are required but all targets require the same form data to the be posted.

A common scenario here is that you might have a button (or link) that you click where you still want some server code to fire but at the end of the request you actually want to display the content in a new window. A common operation where this happens is report generation: You click a button and the server generates a report say in PDF format and you then want to display the PDF result in a new window without killing the content in the current window. Assuming you have other buttons on the same Page that need to post to base window how do you get the button click to go to a new window?

Can't  you just use a LinkButton or other Link Control?

At first glance you might think an easy way to do this is to use an ASP.NET LinkButton to do this - after all a LinkButton creates a hyper link that CAN accept a target and it also posts back to the server, right? However, there's no Target property, although you can set the target HTML attribute easily enough.

Code like this looks reasonable:

     <asp:LinkButton runat="server" ID="btnNewTarget" Text="New Target" 
                     target="_blank"  OnClick="bnNewTarget_Click" />

But if you try this you'll find that it doesn't work. Why? Because ASP.NET creates postbacks with JavaScript code that operates on the current window/frame:

<a id="btnNewTarget" target="_blank" 
href="javascript:__doPostBack(&#39;btnNewTarget&#39;,&#39;&#39;)">New Target</a>

What happens with a target tag is that before the JavaScript actually executes a new window is opened and the focus shifts to the new window. The new window of course is empty and has no __doPostBack() function nor access to the old document. So when you click the link a new window opens but the window remains blank without content - no server postback actually occurs.

Natch that idea.

Setting the Form Target for a Button Control or LinkButton

So, in order to send Postback link controls and buttons to another window/frame, both require that the target of the form gets changed dynamically when the button or link is clicked. Luckily this is rather easy to do however using a little bit of script code and jQuery.

Imagine you have two buttons like this that should go to another window:

        <asp:LinkButton runat="server" ID="btnNewTarget" Text="New Target" 
                        OnClick="ClickHandler" />

        <asp:Button runat="server" ID="btnButtonNewTarget" Text="New Target Button" 
                    OnClick="ClickHandler" />

ClickHandler in this case is any routine that generates the output you want to display in the new window. Generally this output will not come from the current page markup but is generated externally - like a PDF report or some report generated by another application component or tool. The output generally will be either generated by hand or something that was generated to disk to be displayed with Response.Redirect() or Response.TransmitFile() etc.

Here's the dummy handler that just generates some HTML by hand and displays it:

protected void ClickHandler(object sender, EventArgs e)
{
    // Perform some operation that generates HTML or Redirects somewhere else
    Response.Write("Some custom output would be generated here (PDF, non-Page HTML etc.)");
    
    // Make sure this response doesn't display the page content
    // Call Response.End() or Response.Redirect()
    Response.End();
}

To route this oh so sophisticated output to an alternate window for both the LinkButton and Button Controls, you can use the following simple script code:

    <script type="text/javascript">
        $("#btnButtonNewTarget,#btnNewTarget").click(function () {
            $("form").attr("target", "_blank");
        });
    </script>

So why does this work where the target attribute did not? The difference here is that the script fires BEFORE the target is changed to the new window. When you put a target attribute on a link or form the target is changed as the very first thing before the link actually executes. IOW, the link literally executes in the new window when it's done this way.

By attaching a click handler, though we're not navigating yet so all the operations the script code performs (ie. __doPostBack()) and the collection of Form variables to post to the server all occurs in the current page. By changing the target from within script code the target change fires as part of the form submission process which means it runs in the correct context of the current page. IOW - the input for the POST is from the current page, but the output is routed to a new window/frame. Just what we want in this scenario.

Voila you can dynamically route output to the appropriate window.

Posted in ASP.NET  HTML  jQuery  

The Voices of Reason


 

Martillo
January 31, 2011

# re: Changing an HTML Form's Target with jQuery

Very cool. An interesting scenario would be to use this technique in a CrossPagePostBack so that (if necessary) the target page could access the form values from the first page via the PreviousPage property.

sam
January 31, 2011

# re: Changing an HTML Form's Target with jQuery

very useful article, just have a question, have to set the new window properties like width,...
Thanks.

Jeff
February 02, 2011

# re: Changing an HTML Form's Target with jQuery

Good post, as always, but have you noticed that literally everything you want to do with webforms requires a hack or workaround? It's always some rudimentary thing that is easy to do in any other web platform or framework, but the webforms abstraction always rears it's ugly head. Bleh, the further I get away from webforms, the more productive I have become.

Rick Strahl
February 03, 2011

# re: Changing an HTML Form's Target with jQuery

@Jeff - this isn't specific to WebForms as I pointed out at the top of the page. The same applies to MVC or any other framework that has multiple POSTable options for submission. Admittedly, with WebForms your options are more limited as you can't easily add additional forms, but when you need to submit form variables to multiple target actions there are no choices regardless of platform...

@Sam - if you need to set window properties you need to use JavaScript to open the window (ie. onclick="window.open()" etc.). You can do this with hyperlinks easily enough. With forms you'd have to capture open the window first, THEN submit the form and set the target to the window name that was created...

siddharth borania
February 07, 2011

# re: Changing an HTML Form's Target with jQuery

Learn another use of jquery.Good to know.

Somnath
May 09, 2011

# re: Changing an HTML Form's Target with jQuery

I haven’t executed this code yet.
But just curious to know “what will happen to next button click” after we change form’s target attribute. Assuming (as I said I haven’t executed code yet) original form will be present there as-is because we have posted data in new form, target attribute will be applicable to all future button clicks…

right?

Andon
August 10, 2011

# re: Changing an HTML Form's Target with jQuery

Thanks, this was just what I was looking for! While the given examples with 'a' tags work quite nicely, I couldn't get a new page to be launched my custom GridView's clickable TRs (using CSS selectors with jQuery to bind the click() function).

Instead, I got it working by adding onmouseup attributes to each row, and within the associated method running $("form").attr("target", "_blank").

Ta.

Chris
November 09, 2011

# re: Changing an HTML Form's Target with jQuery

Great stuff Rick. Been tearing my hair out with this one for the last day or so. Your code worked an absolute treat!

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024