Framing Active Server Pages
by Mark Trescowthick - GUI Computing
One of the major irritants about ASPs is that they don't allow a target to be specified in a response.redirect, which makes them a real pain for use in framed environments. This seems a real oversight by Microsoft (or perhaps not, given my recent discoveries about Word's similar inability), but I prefer to see it as the $50 Billion Man's way of providing intellectual stimulation.
In any event, there are two ways to achieve the display of ASP-generated HTML in a frame.
The simplest is to set the base target of the HTML page from which the ASP is called. This provides an easy solution for most circumstances, but sometimes you need to get a bit more complex, in which case the best solution is to actually have the ASP generate the frameset "on the fly" as it were.
To illustrate both methods, I decided to write a simple "meta-search" engine. This engine allows me to search up to four places at once (AltaVista, the MS Knowledge Base, The AVDF Newsgroup Archive and AVDF itself) and display the results in a number of frames. I've included the source, but it really is straightforward.
The Frameset itself is unremarkable, just displaying a left panel, which contains the search form, and a blank right panel, into which we'll insert some additional frames.

The only key lines in the Search form are the Base Target set :
<base target="_top">
and the
<form action="private/doSearch.asp">
Everything else is just your standard HTML form, in reality. Though I did have to figure out what the exact values for the Microsoft knowledge base values were, of course. You'll also note that I provide the option of presenting the search results in separate windows, rather than frames.
The ASP involved, doSearch.asp, is a little more interesting.
I first collect all the information from the form and, importantly, URLEncode the search topic. Without URL encoding, it would be passed as a string and while that will work if it's just a simple word, any spaces or other characters cause all sorts of problems. As I've already said, the search area for the MS knowledge base I derived by the simple expedient of trying each area I wanted to see what its appropriate string was.
<%
searchTopic = request.form ("SearchTopic")
searchTopic = server.urlencode(searchTopic)
searchArea = request.form ("SearchArea") 'only used for MSKB
viewtype = request.form("viewtype") 'spawn or frame
Having established this, I can then set up the URLs required. Each is a little different, of course, and the way I established each was simply by navigating to the site and doing a search, then copying the resulting URL. Actually, that's not quite true, as the AVDF Newsgroup Archive search engine doesn't expose its syntax. After a quick look at the HTML source (isn't it just wonderful you can view the source of pretty much every page on the Net?) I guessed, and guessed right, that it would be happy if I provided it with a query string containing those values it was obviously looking for :
frcount = 0
if request.form("AltaVista") = "ON" then
AVurl = "http://www.altavista.yellowpages.com.au/cgi-bin/telstra?pg=q&what=web&fmt=.&q=" & SearchTopic
frcount = 1
end if
if request.form("mskb") = "ON" then
MSurl = "http://search.microsoft.com/searchbin/kb/mts_search.idq?Hdr=@KBArea&Scope=/kb/articles/&Tmplt=mts_search&SWR=F&Sort=rank[d]&Purl=/kb&Pfx=kb&Base=kb&sl=NULL&KBD=" & SearchArea & "&maxp=25&maxr=100&Sz=" & SearchTopic
frcount = frcount + 1
end if
if request.form("AVDF") = "ON" then
AVDFurl = "http://www.gui.com.au/gcgi/glance?tp=search.gl&query=" & SearchTopic & "&case=on&whole=on&area=All+Issues&errors=0+%28Exact+match%29&maxfiles=10&maxlines=10"
frcount = frcount + 1
end if
if request.form("news") = "ON" then
NEWSurl = "http://www.gui.com.au/gcgi/news_search?query=" & SearchTopic &"&maxresults=50&rtype=1"
frcount = frcount + 1
end if
Having first established that I do, indeed, have something to display, it's then a matter of deciding how many frames I need to generate (based on frcount) and setting up the HTML percentage split string and I'm done.
<%if viewtype = "frame" then ' ' Figure splits (if frames) ' clumsy, but effective! ' splitpct = fix(100/frcount) pcts = Cstr(splitpct) if frcount = 1 then pctstr = pcts & "%" end if if frcount > 1 then pctstr = pctstr & "," & pcts & "%" end if if frcount > 2 then pctstr = pctstr & "," & pcts & "%" end if if frcount = 4 then pctstr = pctstr & "," & pcts & "%" end if end if %>
One of the downsides of ASP development is that you're working for much of the time in two languages (VBScript and HTML) simultaneously. In Visual Interdev, Microsoft take the approach of syntax highlighting the HTML and leaving the VBScript (or JavaScript, if that's your preference, in yellow. Personally, I'd prefer it 100% the other way, as the HTML is far easier to debug that the VBScript in most cases. I've been nagging Ed for Windows guru Neville Franks to provide syntax highlighting for both simultaneously and he tells me he'll get to it "soon". If you'd like to send him email to back up my request, that would probably speed things up! Microsoft tell me they have no plans in the short term to do so... yuk!
Anyway, the HTML here is pretty straightforward. What I do is, if the user has requested frames, generate a frameset with the URLs I've strung together as the source of the various frame components.
<html>
<head>
<title>Intranet Search</title>
</head>
<%if viewtype = "frame" then %>
<frameset cols="20%,80%">
<frame src="../searchside.htm">
<frameset rows="<%=pctstr%>">
<%if AVurl <> "" then %>
<frame src="<%=AVurl%>" name="AltaVista">
<% end if %>
<%if AVDFurl <> "" then %>
<frame src="<%=AVDFurl%>" name="AVDF">
<% end if %>
<%if NEWSurl <> "" then %>
<frame src="<%=NEWSurl%>" name ="news">
<% end if %>
<%if MSurl <> "" then %>
<frame src="<%=MSurl%>" name = "mskb">
<% end if %>
</frameset>
<noframes>
<body>
<p>This web page uses frames, but your browser doesn't support them.</p>
</body>
</noframes>
</frameset>
In the end, it looks like this :
Of course, the user may have requested the information in separate windows. To do this, I had to resort to client-side scripting. I normally don't do this as it means I'm relying on the browser to support and action my code... I don't know about you, but I always feel a little concerned with the words "rely" and "browser" in the same sentence. That's one of the things I like best about ASP - all you have to rely on the browser to do is display vanilla HTML, and most of them can manage that most of the time.
But I know of no way to generate new windows from the server side, so client-side JavaScript it had to be (I'd use VBScript, but that would make me even more vulnerable to the browser wars).
<Script language="JavaScript" for="window" event="onLoad()">
<!--
<%if AVurl <> "" then %>
window.open ("<%=AVurl %>")
<% end if %>
<%if AVDFurl <> "" then %>
window.open ("<%=AVDFurl %>")
<% end if %>
<%if NEWSurl <> "" then %>
window.open ("<%=NEWSurl %>")
<% end if %>
<%if MSurl <> "" then %>
window.open ("<%=MSurl%>")
<% end if %>
Window.location.href = "../frsearch.htm" 'back to search
-->
</Script>
Now, of course, I'm working in three languages simultaneously... not, I would submit, where you want to be!
But it works...