Hi,
Yesterday I was asked a simple question about using a separate browser window for selecting a value and then using the selected value in the main browser window. I’ve done this before but I realized that for a novice web programmer it is not trivial especially when you are accustomed to the ASP.Net programming model.
Let’s consider the following scenario. You are editing an order for buying some books. You enter your name, address, and other information in the textboxes, but you are then required to select the book you are searching for. The problem the programmer is facing is that on one hand he has alot of books in the database (let’s say 5000 items), which means that it would be overkill to fill a dropdown with those names and hard for the user to select from it (too many options), on the other hand ussually he does not have the space to put a complex search in place. So the most ideal situation is to put a separate window that opens on command and where the user can use a more complex algorithm to search for the book he wants. Ok, this is not a very good example as in real world you first select the book, add it to cart and then go to the checkout and fill all remaining data. Still let’s say this is ok for the sake of the demonstration.
So, we have a main window and from there we must open a second window where the user selects some data, then the selected data must be passed back to the main window. Well, ASP.Net does not offer something out of the box for this as the Asp model is based on a single window. So what you can do with asp is to redirect the page to a search window and then upon selecting the desired value redirect it back to the main window and put the values there (you can pass the values either through the Session object or QueryString). This unfortunately requires some extra programming and also might be a little bit difficult for the user to understand.
Thus we get the the javascript sollution. User clicks on a button, a new browser window opens, user makes selection, the new browser window closes and the selection is put in the main window. Below you can find an example and some explanations.
This is the main window:
<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”master.aspx.cs” Inherits=”_master” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head runat=”server”>
<title>Master window</title>
<script language=”javascript” type=”text/javascript”>
function openChildWindow(tagetControlId)
{
var s= “child.aspx?id=”+tagetControlId;
window.open(s,“”,“width=400,height=200,status=no,toolbar=yes,menubar=no,location=no”);
return false;
}
</script>
</head>
<body>
<form id=”form1″ runat=”server”>
<div>
<asp:TextBox ID=”txtResult” runat=”server”></asp:TextBox>
<asp:Button ID=”btnOpen” runat=”server” Text=”Open child” OnClientClick=”openChildWindow(’txtResult’)” />
</div>
</form>
</body>
</html>
This is the child window:
<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”child.aspx.cs” Inherits=”child” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”><html xmlns=”http://www.w3.org/1999/xhtml” >
<head runat=”server”>
<title>Child window</title>
<script language=”javascript” type=”text/javascript”>
function Done()
{
p = window.opener.document; //parent window
target = p.getElementById(GetElementFromQuery(location.search.substring(1),“id”));
target.value = document.getElementById(“txt1″).value+“|”+document.getElementById(“txt2″).value;
window.close();
}
function GetElementFromQuery(url, name)
{
x = url.split(“&”);for (i=0;i<x.length;i++)
{
if (x[i].split(“=”)[0] == name)
{
return x[i].split(“=”)[1]
}
}
return “”;
}
</script>
</head>
<body>
<form id=”form1″ runat=”server”>
<div>
<asp:TextBox ID=”txt1″ runat=”server”></asp:TextBox>
<asp:TextBox ID=”txt2″ runat=”server”></asp:TextBox>
<asp:Button ID=”Select” runat=”server” OnClientClick=”Done()” Text=”Close”/>
</div>
</form>
</body>
</html>
So, let’s summarize. In the main window, which I called master, you have a textbox where we want to put the results and a button which when pressed we want to open the child window. Observe that we use the OnClientClick instead of OnClick since we will be calling a javascript function and there is no need to go to the server (Reminder: OnClientClick is fired before OnClick and in the javascript code of the OnClientClick if we return false, the OnClick will not be fired anymore).
The javascript function called on the click event is “openChildWindow” which has as parameter the id of the control that will receive the selection made in the child window. In the method we construct the URL of the child window where we will pass the id as a query string, then we use the window.open to open the child in a separate browser window.
In the child window we have 2 textboxes from where we will take the selection. When the user presses the button, the “Done” function will first retrieve the opener object, which is a handle to the window that oppened the child window (this is normally null, unless the window was opened as a result of a window.open call). then we retrieve the html object from the opener window that has as id the string passed as query string. we use a separate function for that, which will search within the query string the keyvaluepair with the specified key and retrieve the value (we used “id” as we sent it like this from the master window). Afterwards we set the value of the target element with the values from the two textboxes and close the window.
This is highly extensible as the child window can host a normal ASPX page and the results can be multiple and returned in various locations within the master page (just use more keys in the QueryString).
That’s it for now. Feel free to adapt the above code to your needs and post any questions you might have.
Edit: You can find also a more detailed example here