Using RadWindows for calling common dialogs

Thread is closed for posting
1 posts, 0 answers
  1. CE8FD5B8-D57F-4131-8A9A-47DA58D4A301
    CE8FD5B8-D57F-4131-8A9A-47DA58D4A301 avatar
    1622 posts
    Member since:
    Jul 2004

    Posted 10 Feb 2011 Link to this post

    Requirements

    RadControls version Q1 2010

    .NET version 2.0+

    Visual Studio version 2008+

    programming language C#

    browser support

    all browsers supported by RadControls


    PROJECT DESCRIPTION
    The requirements represent the lowest versions of stuff that I've tried the following with.

    We've all used RadWindows for showing 'Common' dialogs, like a Contact picker or document picker, from another page, right? Likewise, we've all used RadWindows for popup forms. How many of you, though, have found yourself in a position where you need to access a 'common' dialog from one of your popup windows?

    For those of you that haven't, let me, briefly, explain the issues. Basically the problem is one of size. When you open a RadWindow (common dialog) from inside a page that itself in a RadWindow (popup form) then the window for the common dialog is constrained to the limits of the popup form's window. One fudge that I employed to get around this, was to maximize the popup form and hide it's titlebar before showing the common dialog. It works -ish. There is sometimes an issue with the popup page resizing after the common dialog is closed and there is a lot of 'unexpected' (by the end-user) activity on the page before the common dialog opens.

    It's not ideal.

    The solution is to make sure that common dialog is opened by the main page, ie the one that opens the popup window. Making this happen is relatively straightforward and achieved using a technique described in this documentation article for calling a JavaScript function on a page from a page in a RadWindow. However, the article doesn't cover the issue of what to do if your popup window needs to run a JavaScript function when the common dialog closes, to, for example, process the results of the actions in the common dialog.

    This article describes a technique that allows you to put the common dialog code on the MAIN PAGE, call it from your popup and - and this is the important bit - allow your popup page the process the common dialog's results.

    Let's look at a simple example made up of:
    • MainPage.ascx - the page from which all activity begins
    • PopupPage.aspx - a page displayed in a RadWindow opened from MainPage.aspx
    • CommonDialog.aspx - our common dialog.
    To better simulate doing this for real, I've included a control CommonDialogControl.ascx which we will use as a means of accessing the common dialog.

    Let's look at the control first. The markup and code behind are below...

    <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="CommonDialog.ascx.cs" Inherits="CommonDialog" %>
    <telerik:RadScriptBlock ID="RadScriptBlock1"
                            runat="server">
        <script type="text/javascript">
     
     
            function OpenCommonDialogRemote(callerID)
            {
                var wnd = $find("<%= cdCommonDialog.ClientID %>");
                wnd.add_close(CommonDialogRemoteClose);
                wnd.show();
     
     
                function CommonDialogRemoteClose(sender, e)
                {
                    sender.remove_close(CommonDialogRemoteClose);
                    var mgr = sender.get_windowManager();
                    var caller = mgr.getWindowByName(callerID);
                    if (caller)
                    {
                        caller.get_contentFrame().contentWindow.CommonDialogRemoteClose(e.get_argument());
                    }
                }
            }
     
     
            function OpenCommonDialog(CommonDialogClose)
            {
                var wnd = $find("<%= cdCommonDialog.ClientID %>");
     
     
                wnd.add_close(CommonDialogClose);
                wnd.show();
            }
        </script>
    </telerik:RadScriptBlock>
    <telerik:RadWindow runat="server"
                       ID="cdCommonDialog"
                       Width="800px"
                       Height="600px"
                       NavigateUrl="CommonDialog.aspx">
    </telerik:RadWindow>

    public partial class CommonDialog : System.Web.UI.UserControl
    {
        public void Register(RadWindowManager WindowManager)
        {
            WindowManager.Windows.Add(cdCommonDialog);
        }
    }

    The markup contains a script block with 2 functions and a RadWindow definition.

    The 2 JavaScript functions are there to allow the window to be opened. The first, OpenCommonDialogRemote(), allows the common dialog to be opened from within another RadWindow, the 2nd, OpenCommonDialog(), is used to open the same dialog from the main page.

    Note that the window is defined without use of a RadWindowManager.

    The OpenCommonDialogRemote() function is the one we're interested in here. This function finds the window, associated a function with the OnClientClose event and show the window. The function used for the ClientClose event is nested within this function. It is the nested function that does the work of allowing the calling page (our PopupPage) to execute a local javaScript function to process the result of the call to the common dialog. Again, it uses a technique from this article for allowing a JavaScript function on a page in one RadWindow to call a JavaScript function on a page in another RadWindow.

    The keen eyed amongst you will have noticed this line ...

    var mgr = sender.get_windowManager();

    and will have remembered that our window is defined without benefit of a RadWindowManger. I'll cover this very shortly. Assume for the moment that our call to get_windwowManager() will return a valid RadWindowManager. The next line looks for a window whose name matches the parameter passed when we opened the dialog then calls a function on it. This function is where the calling page actually processes the results from the common dialog and that is why we pass the result of a call to get_argument() to it.

    OK, let's deal with this issue of the call to get_windowManager(). Obviously, for this to return the RadWindowManager that the calling page (PopupPage) exists on, it must have been set at some point. This is what the Register(RadWindowManager) method in the code-behind is for. When the common dialog control is put on the MainPage, a call to the dialog's Register() method is made (I do it in the page's OnInit handler). This call passes the page's RadWindowManager (the one also used to open PopupPage) as a parameter. This call registers the window with the window manager and so the call to get_windowManager() works!

    Our MainPage.aspx can be as complex or as simple as you like, it simply needs a call to register the .ascx control on the page as an instance of the control in the markup. As previously stated, the code behine needs to call the control's Register() method.

    Likewise, our popup page can, again, be as complex as you need it to be. It will probably have a AjaxRequest handler to receive the results of the call to the common dialog and to process them. However, it must have a mechanism to call the common dialog and another to process the results.

    The first of these, the call to open the dialog, can be just the following 2 lines of script...

    var wnd = GetRadWindow();
    wnd.BrowserWindow.OpenContactPickerRemote(wnd.get_name());

    The GetRadWindow() function called is the one described in the RadWindow documentation. The 2nd line finds the browser window that the RadWindow exists in and calls a function in it. Note how we pass the name of the calling window...

    wnd.get_name()

    You could just put in a string value, but using this method means that this script code could be part of a control itself, which might be used on many different pages and in many different popups.

    The 2nd function which must exist is the function called by the common dialog control...

    caller.get_contentFrame().contentWindow.CommonDialogRemoteClose(e.get_argument());

    The following is a simple example of this function...

    function CommonRemoteClose(e)
    {
        alert("Popup Page gets '" + e + "' from Common dialog");
    }

    This is a more complex one ...

    function ContactPickerRemoteClose(e) {
        if (e != null) {
            var AjaxRequestObject = new Object()
            AjaxRequestObject.CommandName = "ProcessCommonDialogResults"
            AjaxRequestObject.ListOfStuff = e.ListOfStuff;
            // Call to generate an AjaxRequest goes here
        }
    }

    Here our return object (e) is complex data type serialized using JSON for transport from the common dialog to the calling page

    That's it really. I hope that the above all makes sense and that it is actually of some value.

    Have a look. Have a play. Let me know what you think.

    -- 
    Stuart
Back to Top

This Code Library is part of the product documentation and subject to the respective product license agreement.