Basic Window question

18 posts, 0 answers
  1. GcM
    GcM avatar
    7 posts
    Member since:
    Oct 2007

    Posted 26 Oct 2007 Link to this post

    I'm coming from a ASP .NET AJAX / Toolkit background and I'm used to developing windows that follow this pattern:

    In the ASPX I would have an UpdatePanel in the body of the page and a ModalPopupExtender which would contain an UpdatePanel.  The event handler for the trigger on the page would populate values in the ModalPopupExtender's UpdatePanel and then display it via the Show() method.  The event handler for the Save button on the ModalPopupExtender would do any additional validation/persistence and, if successful, update values on the calling page's UpdatePanel and Hide() the dialog window. 

    Is it possible to implement this pattern using the Prometheus Window and AjaxPanel/AjaxManager without having to write Javascript?
  2. Shaun Peet
    Shaun Peet avatar
    571 posts
    Member since:
    Aug 2004

    Posted 28 Oct 2007 Link to this post

    I think the tooltip may be better suited to follow that pattern (to write *no* javascript).

    If you're up for writing a very small amount of javascript, you can do what you're trying to do by:

    1) Having a script function that triggers an update on the parent page to refresh your data.
    2) Open the window, loading into it an aspx page containing your data entry form - passing values into it using the QueryString.
    3a) Use the onClientClose of the window to call the parent page's script to update the data
    -- or --
    3b) Create a javascript function in the window's aspx page that gets a reference to itself (ie. GetRadWindow()) - and then use that object to call the BrowserWindow.yourJSfunction() to call the parent page's script to update the data and then close the window.

    I use this method - alot - and it works extremely well and fast.  The way I've got it setup I use a MasterPage for both the parent pages and the window pages - so the only thing that changes is the url of the window page.  I've also got a little javascript function in the window's master page that resizes the window based on the server-side code in the page_load event.

    If interested, I can post the relevant code.
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. GcM
    GcM avatar
    7 posts
    Member since:
    Oct 2007

    Posted 29 Oct 2007 Link to this post

    Thanks a lot for the information.  I would definitely be interested in seeing the details of your implementation. I'm sure it would save me from making some mistakes as I come up to speed.  Thanks again.
  5. Shaun Peet
    Shaun Peet avatar
    571 posts
    Member since:
    Aug 2004

    Posted 29 Oct 2007 Link to this post

    Ok, here comes all my trade secrets...

    I will refer to the pages that displays the data as the "parent" pages and the pages that open within the window as "window" pages.  Both the parent pages and the window pages use a respective MasterPage.

    The parent page's MasterPage has the following javascript function:

    function postBackHF(HFID) { var hF = $get(HFID); if (hF) { hF.value = (new Date()).getTime(); __doPostBack(HFID,''); } }

    Each parent page has an asp:HiddenField on it, located within an asp:UpdatePanel.  This function takes the client ID of that hidden field, and if found, changes the value of the hidden field.  The parent page then has server-side code that executes with the ValueChanged event for the hidden field.  For example, in the parent page markup:

    <
    asp:HiddenField ID="hfUC" runat="server" OnValueChanged="hfUC_ValueChanged" />

    and in the parent page code (VB, in this case):

    Protected
    Sub hfUC_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs)
    ' UPDATE YOUR DATA HERE
    End Sub

    The real beauty of ths is the fact that you can segment your parent page into various asp:UpdatePanels, and then place an asp:HiddenField into each.  So long as the associated ClientID of the hidden field is passed into the postBackHF() function, only the corresponding part of the page will be updated.

    Now, back to the parent pages MasterPage file.  There is also a javascript function as follows:

    function
    OpenModal(url) { var oManager = GetRadWindowManager(); var oWnd = oManager.GetWindowByName("rwForm"); oWnd.setUrl(url); oWnd.show(); return; }

    In my experience, even though the RadWindowManager is no longer required for Prometheus, it still seems to work better this way, so in the parent page's MasterPage there is the following markup.

    <
    telerik:RadWindowManager runat="server" ID="rwmModal">
      <Windows>
        <telerik:RadWindow runat="server" ID="rwForm" />
      </Windows>
    </telerik:RadWindowManager>

    And that's all there is to the parent pages MasterPage file.

    In order for the rest of this to make sense, I will provide a specific example of how I use this.  Namely, there will be a parent page that has a list of news articles that have been submitted to the site, and a corresponding "news article form".  So, each parent page has, in addition to the asp:UpdatePanel and asp:HiddenField as stated above, javascript functions that are called to open the window.  In this case, we will have two functions; one that opens the window in "New" mode, and one that opens the window in "edit" mode:

    function
    ShowNewArticleForm(HFID) { OpenModal('../Modals/Article.aspx?Mode=New&HFID=' + HFID); return false; }

    function ShowEditArticleForm(ID, HFID) { OpenModal('../Modals/Article.aspx?ID=' + ID +'&HFID=' + HFID); return false; }

    As you can see, both of these functions call the OpenModal() function that is on the MasterPage.

    In order to trigger these functions, I have set the "onClick", or, in some cases, the "onDblCick" attributes of various HTML elements in the server-side code.  For example, I have a "Create New Article" button, which is actually a <span> element with runat="server" on the page.  In the Page_Load event:

    spNew.Attributes.Add(
    "onClick", "return ShowNewArticleForm('" & hfUC.ClientID & "')")

    That takes care of opening the "new article" form.  The parent page in this case would have a list of articles, say, in a repeater called "rptList".  So, the server-side code would include:

    Protected
    Sub rptList_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rptList.ItemDataBound
      Select Case e.Item.ItemType
        Case ListItemType.Item, ListItemType.AlternatingItem
        Dim div As HtmlGenericControl = e.Item.FindControl("nlItem")
        Dim ARTICLEid As Integer = e.Item.DataItem("ID")
        div.Attributes.Add(
    "onDblClick", "ShowEditArticleForm(" & ARTICLEid & ",'" & hfUC.ClientID & "')")
      End Select
    End Sub

    So that takes care of opening the window.  The finishing touches involve creating the "Article.aspx" window page.  But first, here's the window MasterPage javascript functions:

    function
    get_RadWindow() { var oWindow = null; if (window.radWindow) { oWindow = window.radWindow; } else if (window.frameElement.radWindow) { oWindow = window.frameElement.radWindow; } return oWindow; }

    Which gets a reference to the client-side window object.

    function
    CloseAndRebind(HFID) { get_RadWindow().BrowserWindow.postBackHF(HFID); get_RadWindow().Close(); }

    Which calls the parent page postBackHF function, passing the hidden field's Client ID (which was brought in using the querystring of the window page), and then also closes the window.

    function
    JustRebind(HFID) { get_RadWindow().BrowserWindow.postBackHF(HFID); }

    Which just calls the postBackHF function and leaves the window open.

    function
    JustClose() { get_RadWindow().Close(); }

    Which just closes the window.

    Using the last one is easy.  Simply set the onclick attribute (or the onClientClick property) to be "JustClose()".  I use this as a "Cancel" link in a window page.  The other two require that script is injected into the response after an event happens (for example, an "Update" link is clicked).  To make this seamless, I also include on the window MasterPage a RadAjaxManager as follows:

    <
    telerik:RadAjaxManager ID="ramModal" runat="server" />

    So, let's say that the Article.aspx window page is a simple FormView control, that uses the ID of the article in the querystring to display the data in EditMode, or changes to InsertMode if the "Mode=New" parameters are in the querystring.  I can then wire up the FormView's ItemInserted and ItemUpdated events with the following code:

    CType
    (Master.FindControl("ramModal"), RadAjaxManager).ResponseScripts.Add("CloseAndRebind('" & Request.QueryString("HFID") & "')")

    And voila!, the parent page is "refreshed" and the window is closed.

    That's all there is to it (which may seem like alot, but 99% of this can be re-used for every page that you make), and the performance is really quite good.  The real beauty of this methodology is that the window pages can be heavily customized for the data that they are meant to handle.  For example, the Article.aspx page will probably have a r.a.d.Editor on it while other window pages could have calendars, input controls, etc. etc. etc.

    In my futher attempts to minimize the amount of work I need to do in order to expand my projects, I have also created a javascript function that is added to the window pages MasterPage that resizes the window:

    function
    set_WindowSize(w,h) { var oWnd = get_RadWindow(); if (h > oWnd.BrowserWindow.getPaneHeight()) { h = oWnd.BrowserWindow.getPaneHeight() - 80; w = w + 30; } oWnd.set_Height(h); oWnd.set_Width(w); oWnd.center(); return; }

    This calls a function on the parent page that I have setup that gets the height of the splitter pane that it happens to be in, and then checks that the height of the window doesn't exceed the height of the pane, and then sets the size of the window accordingly.  To make this work, I then add the following in the Page_Load for the window page:

    Page.ClientScript.RegisterStartupScript(Type.GetType(
    "System.String"), "SetSize", "set_WindowSize(700,500);", True)

    Hope that helps!

  6. GcM
    GcM avatar
    7 posts
    Member since:
    Oct 2007

    Posted 30 Oct 2007 Link to this post

    Wow!  Thanks for all your help.  I'll keep your trade secrets closely guarded. ;-)

    Thanks again.
  7. Shaun Peet
    Shaun Peet avatar
    571 posts
    Member since:
    Aug 2004

    Posted 30 Oct 2007 Link to this post

    No problem.  Let me know if you spot any improvements!
  8. cserold
    cserold avatar
    2 posts
    Member since:
    Aug 2006

    Posted 31 Oct 2007 Link to this post

    This post was extremely helpful.  Shaun, can you offer any guidance for best practices of doing standard ASP.NET forms validation inside a RadWindow?  Basically, I need to perform the validation on in a server-side event in the window page and, if the user is validated successfully, close the window page and perform the "RedirectFromLoginPage" on the parent page.  Does that make sense? Thanks Shaun.
  9. Shaun Peet
    Shaun Peet avatar
    571 posts
    Member since:
    Aug 2004

    Posted 31 Oct 2007 Link to this post

    It sort of makes sense; I think.  I'm assuming you want to use the Window to have a "Login.aspx" style page, and the close the Window upon logging in and then redirecting somewhere else.

    Using the "normal" methodology for logging in, a "Login" link posts-back to the server, calling the FormsAuthentication.RedirectToLoginPage() method.  So you then end up on the login page which also has a "ReturnUrl=" parameter in the querystring.  Upon successful login, ASP.NET uses that parameter to go back to the page where the "Login" link was clicked - UNLESS - you have manually told the asp:Login control to go somewhere else upon logging in.

    So back to your scenario then.  If using the default path as above - where the user is returned to the "original" page; you wouldn't need to redirect to a different page; you just need to reload the current parent page.  However, if you always want to go to a different page upon successful login, then you can just do the Response.Redirect() to the desired page.

    This is where it gets tricky.  My method above shows how you can trigger a postback on the parent page and then close the window page.  I'm not exactly sure what the effects would be if you reversed the order - closing the window first and then posting back.  My initial testing shows that this might work.  So, instead of:

    function CloseAndRebind(HFID) { get_RadWindow().BrowserWindow.postBackHF(HFID); get_RadWindow().Close(); }

    you would have:

    function
    CloseAndRebind(HFID) { get_RadWindow().Close(); get_RadWindow().BrowserWindow.postBackHF(HFID); }

    So, upon posting back the parent page you simply call Response.Redirect(Request.Url.ToString) or Response.Redirect("SomeOtherPage.aspx") as necessary.  Just for fun, I tested whether or not you can get away with doing a Response.Redirect and my quick testing revealed that yes, you can.

    Hope that helps.

  10. cserold
    cserold avatar
    2 posts
    Member since:
    Aug 2006

    Posted 31 Oct 2007 Link to this post

    Shaun,
    I wanted to thank you again for going above and beyond with the details of post.  The methodology you outlined in this thread is SOOOO helpful.

    Thanks again,
    Craig
  11. Shaun Peet
    Shaun Peet avatar
    571 posts
    Member since:
    Aug 2004

    Posted 01 Nov 2007 Link to this post

    No problem, I'm glad I could help.  Maybe if the telerik guys get a chance someday they can have a look at the code and see if there's any other improvements that can be made.  My current code has gone through the polisher a few times already ;)
  12. Georgi Tunev
    Admin
    Georgi Tunev avatar
    7207 posts

    Posted 02 Nov 2007 Link to this post

    Hello Shaun,

    Your code looks very good and for now we cannot suggest any significant improvements on it. On the behalf of Telerik's staff  I would like to thank you for sharing it in the forums. 

    If it is not a problem for you, I invite you to prepare a small sample project which uses your approach and to upload it in the Code Library section of our site - I am sure it will be very useful for the whole community




    Have a great weekend,
    Georgi Tunev
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  13. Shaun Peet
    Shaun Peet avatar
    571 posts
    Member since:
    Aug 2004

    Posted 02 Nov 2007 Link to this post

    I started that process last night and will hopefully have something by next week.
  14. Georgi Tunev
    Admin
    Georgi Tunev avatar
    7207 posts

    Posted 02 Nov 2007 Link to this post

    It is great to hear that Shaun :)


    Once again, thank you for your dedication and efforts.




    Best wishes,
    Georgi Tunev
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  15. Shaun Peet
    Shaun Peet avatar
    571 posts
    Member since:
    Aug 2004
  16. Georgi Tunev
    Admin
    Georgi Tunev avatar
    7207 posts

    Posted 13 Dec 2007 Link to this post

    Hi Shaun,

    Thank you for the article - I am sure the community will benefit from it.



    Sincerely yours,
    Georgi Tunev
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  17. Chris
    Chris avatar
    6 posts
    Member since:
    Jun 2007

    Posted 10 Jan 2009 Link to this post

    I was looking for a standard way to handle the editing of data with a popup window when I came across this "oldie but a goodie" thread.  I downloaded and played with the Code Library that Shaun provided.

    I came across an issue when I had my "List" be in the form of a RadGrid.  I believe the issue is related to the data binding but I can't seem to figure it out.  Here is my setup:

    List Page:
    A basic RadGrid inside of RadAjaxPanel (and I have tried a regular UpdatePanel).  In side of this Panel I have included the Hidden field.  In the code behind on the Page_Load event, I have the standard "hook up the grid's datasource if it is not a postback" code.  In the Hidden field's OnValueChanged event, I have the code to rebind the grid when the popup window closed with a rebind.

    When I run the page and trigger the popup, the window displays and I am able to update my data.  When I click the Update button, the data is saved and the popup closes. 

    Here is were the problem shows up.  On the postback triggered by the closing popup, the OnValueChanged event is never fired.  If I take a peek with Firebug, I see this error: "There was a problem extracting DataKeyValues from the DataSource. Please ensure that DataKeyNames are specified correctly and all fields specified exist in the DataSource".

    This error kind of makes sense since the OnValueChanged event never fired, the RadGrid was never data bound.  For some reason it looks like the RadGrid is looking for data before the Hidden fields event is fired.

    Shuan, have you seen this behavior and if so, how do you deal with it? 

    Thanks

    BTW, I am using the 2008 Q3 release of the Rad Asp.Net Ajax tools
  18. Georgi Tunev
    Admin
    Georgi Tunev avatar
    7207 posts

    Posted 10 Jan 2009 Link to this post

    Hello Chris,

    At this point we cannot say what the reason for the problem might be, but I would suggest to check the following help article and ensure that your setup follows the guidelines shown there:
    http://www.telerik.com/help/aspnet-ajax/grdextractkeyvaluesclientside.html

    If you still experience problems after that, it will be best to open a support ticket and send us a small sample project where this issue can be reproduced. We will check it and do our best to help.


    Best wishes,
    Georgi Tunev
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  19. Hossein Jabbarzadeh
    Hossein Jabbarzadeh avatar
    3 posts
    Member since:
    Dec 2009

    Posted 07 Jan 2011 Link to this post

    Thanks Shaun, It saves me a lot of time. 
    Really, really Appreciate it .

    Thanks
    Hossein
Back to Top
UI for ASP.NET Ajax is Ready for VS 2017