Introduction

When writing accessible websites, we are told that frames are wrong. But with web-applications for the local intranet of your company or your customers, frames can be very useful. But why is it that we ASP.NET developers rarely use frames for our web-applications? Not because we don't like frames, but because ASP.NET limits us to the page we are currently building, disallowing us to reach out of our 'frame' and altering other frames, without refreshing them constantly.

This article is part two of a trilogy, in which I present the AnywherePlaceHolder. A control that functions like a normal PlaceHolder (with children), but that enables you to render the child controls in any frame of your web-application. The control is built in the new ASP.NET 2.0 and uses generics and is deeply coupled with the ASP.NET 2.0 client side JavaScript functions.

In the first part of this article, I presented the BaseAnywherePlaceHolder and the SimpleAnywherePlaceHolder. The SimpleAnywherePlaceHolder was only used to explain the basics of the real AnywherePlaceHolder that will now be explained in part 2. The SimpleAnywherePlaceHolder can write normal controls like Labels, Tables, GridViews to any desired frame.

In this part, I will explain the working of the AnywherePlaceHolder that enables you to write basically any content, including submit buttons, to any other frame, with respect to their functionality. Even JavaScript code will still work.

In part three, I will explain the working of the AnywhereValidationSummaryPlaceHolder. This is a AnywherePlaceHolder with the functionality of a normal ValidationSummary. This is a BaseAnywherePlaceHolder with the functionality of a normal ValidationSummary. This special PlaceHolder allows you to write your custom messages and validation error messages into the frame of choice.

ASP.NET 2.0

This project is written for ASP.NET 2.0, and will not compile under .NET 1.x. However I believe that it can be ported back to .NET 1.x, with a little bit of effort.

Using the code

In this part, we'll be examining the AnywherePlaceHolder class. Below is the class diagram.

The AnywherePlaceHolder solves the problems with JavaScript and submit buttons, that the SimpleAnywherePlaceHolder had. First of all, the AnywherePlaceHolder searches its own control hierarchy to find Button controls that have their UseSubmitBehaviour property enabled. Submit buttons are real nasty animals when injecting code. Logically, because the submit behavior of a Button has no effect, without a Form element. So what we must do is set the UseSubmitBehaviour of all Buttons to false before we buffer the child controls' HTML code.

The submit has also a really important feature. A Form can force a submit when return is pressed within an input control on the page. This allows the user to use the page without the mouse. So when we remove the Buttons from the source this feature will disappear. Iterating all child controls is done with the ControlTree class. Explaining this class is beyond the scope of this article. Download the source code and see how this is implemented.

The solution for this is rather simple. Render the Button controls normally in the source frame with their "submit" behavior enabled, but hide them using the stylesheet 'display' property. Remember the source.style.display = 'none'; line from part one?

Okay, now we fixed the problem with the submit buttons, but still no button will work, because every ASP.NET Button uses JavaScript by default. The buttons are rendered in the destination frame, but must call the JavaScript functions in the source frame. For this we need the SourceFrame property in the BaseAnywherePlaceHolder class. The AnywherePlaceHolder's method ConvertSourceCode does the trick. This method simply searches for predefined JavaScript functions from the ASP.NET 2.0 framework and adds the sourceframe before it. The ConvertSourceCode method is noted below:.

As you can see, the method loops through the AspNetJavaScriptFunctions array and searches for the sixteen defined JavaScript functions. After that it will search for occurrences of this.document.. The only problem you now still have is calling your own JavaScript functions. The current implementation has no solution for this, but some easy tricks could easily be created.

To wrap things up

You have seen that with minimal coding you can create the AnywherePlaceHolder that can beam virtually every control from one frame to another with the speed of light. Images, Buttons, even complete Tables can easily be transported between the frames. But as you already know, there is another part of this article, so what is still missing in this concept? Missing is the possibility to put a ValidationSummary component in another frame. The AnywhereValidationSummaryPlaceHolder will deal with this in The AnywherePlaceHolder. Part 3: The AnywhereValidationSummaryPlaceHolder!

History

22 August, 2005 - Version 1.0. Initial version.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

I discribed in the article that the AnywherePlaceHolder still renders the source element so the user can still press RETURN in a webform when using Submit Buttons. This is done by setting the AnywherePlaceHolder's style to 'display:none' in the source frame.

Problem is that this will actually not work with Internet Explorer. When setting the source element to display:none or visibility:hide, Internet Explorer will disable the complete functionality of the element (and child elements) and so any submit buttons will not work either.

What you should do to solve this problem is let the AnywherePlaceHolder set the element to an absolute position and the transparancy to 0%. This will visually hide the element, but it will still work properly.