Welcome to Tech-Review.Org Sign in | Join | Help

.net_2.0

My coding blog entries. Typically will either be more complex coding examples or overcoming product issues / troubleshooting resolutions.
Troubleshooting Microsoft.Ajax Beta 1: Loss of ScriptManagerRegisteredScriptsBlocks after ModalPopup
In my previous blogs/forum entry, I outlined a workaround for displaying a modal form over top of a gridview.  Now, I am troubleshooting some of the behaviors.


The problem with setting the UpdatePanel (that wraps the Gridview & associated controls) to mode="Always" is that (which btw is not a requirement to make the work around work for FireFox) it does a  postback of the contents of the UpdatePanel on each request for the UpdatePanel.  In other words no asynchronous processing actually takes place for that actual UpdatePanel. 

So, my goal was to troubleshoot and see if there is a cleaner work around at minimum.  I had to close all of the IE sessions I had due to memory issues and once done with that task - I began to notice actual script errors occuring.  No idea why I was not getting them before, but now each time I move over a row in a gridview AFTER invoking the modal popup and closing it, suddenly I get a ton of null reference errors.  Additionally when invoking the Modal I was getting a nasty 'screen flicker' - which is not very pleasant to work with prior to display of the modal.

Interestingly enough - and again - when the page loads the first time - there are NO SCRIPT errors.  Gridview select options work for sorting and such and provides the expected UI experience when ajax enabled.

We can back up a sec.  The gridview uses a java script routine to highlight rows on mouseover and also changes the background row color of a selected item.  Typical UI enhancement for the gridview as it makes it more user friendly especially when working with alot of data.

The code is relatively simple.  On the pre-render phase we register the script into the Script Manager as per the new reuirements for Beta 1.

protected override void OnPreRender(EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                string script = @"
    var _oldColor;
    function SetNewColor(source)
    {  _oldColor = source.style.backgroundColor;
        source.style.backgroundColor = '#00ff00';}
 
    function SetOldColor(source)
    {  source.style.backgroundColor = _oldColor;  }";

                ScriptManager.RegisterClientScriptBlock(this, typeof(Page), "ToggleScript", script, true);
            }


Then in the Gridview's DataBound event we wire up some row behaviors:

      protected virtual void GridView_RowDataBound(Object s, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow )
            {
                //Note: Here is where we change the button submit so that
                //our IPostBackHandler can properly handle AJAX requests.
               
                int editID = (int)DataBinder.Eval(e.Row.DataItem, "id");
                e.Row.Attributes.Add("onMouseOver", "SetNewColor(this);");
                e.Row.Attributes.Add("onMouseOut", "SetOldColor(this);");
                e.Row.Attributes.Add("onDblClick", Page.ClientScript.GetPostBackEventReference(this, e.Row.RowIndex.ToString()));
                e.Row.Attributes.Add("onKeyDown", "if( event.keyCode == 13 ) " + Page.ClientScript.GetPostBackEventReference(this, "KEYDOWN" + "$" + e.Row.DataItemIndex.ToString()));


Typical method of performing this task.  Note that I am only inserting the ScriptManager.RegisterClientScriptBlock(..something) if Page.IsPostBack is true.  The assumption here is that if we are running in "Conditional Mode" (and I would assume should still be in "Always" mode... then everything is async and the Script's are still on the client. 

However, somehow the scripts are not being kept on the client - and thus when the modal closes, the script is lost (probably on the initialization of the ModalPopup), and script errors will abound when moving the mouse over the Gridview.

The only solution is not to check for the postback and always send the script downstream.  Which really makes no sense since the client side is supposed to already have it.  I can understand maybe the requirement for it always being sent if the UpdatePanel mode is "Always" although not really.   Ajax is supposed to only UpdatePanel not the entire page when a asynch request is made.  So, if the ScriptManager has the script registered it should remain so on the client unless the client does a "refresh" from the browser or navigates again to the page (say a menu for the option exists on the page) or any other words the page request is not a postback   For whatever reason, the ModalPopup wipes out the script and maybe the 'flickering of the page' what appears to be a full postback but we know that can be true because the !Page.IsPostBack is false and if it was a full postback - then the script would be sent downstream.

Is there perhaps some guideance on this or is this possibly a bug as well....
Posted: Wednesday, October 25, 2006 1:53 AM by Jody

Comments

No Comments

New Comments to this post are disabled