Showing posts with label MS Ajax. Show all posts
Showing posts with label MS Ajax. Show all posts

Friday, March 23, 2012

UpdatePanel Progress Emulation or How to show "Progress" information when we need to generate full postback (by PostBackTrigger) in the UpdatePanel

Initial data
We have an UpdatePanel. In this UpdatePanel we have two buttons. By clicking each button application does something. Also we have an UpdateProgress for the UpdatePanel. BUT one button generate full PostBack.
<%@ Page Title="Home Page" Language="vb" MasterPageFile="~/Site.Master" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="UpdatePanelProgressEmulation._Default" %>
<%-- It is registration for a web user control that include presentation layout of our progress information. --%>
<%@ Register src="Preloader.ascx"  tagname="Preloader" tagprefix="uc1" %>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <asp:ScriptManager ID="ScriptManagerMain" unat="server"></asp:ScriptManager>

<asp:UpdatePanel ID="UpdatePanelMain" runat="server">
        <Triggers>
            <%--Register our full postback action for button--%>
            <asp:PostBackTrigger ControlID="btnWithPostBackTrigger" />
        </Triggers>

        <ContentTemplate>
            <%--UpdateProgress - uses ucPreloader. As in the above code.--%>
            <asp:UpdateProgress ID="UpdateProgressMain" EnableViewState="false"    AssociatedUpdatePanelID="UpdatePanelMain" runat="server">
                <ProgressTemplate>
                    <uc1:Preloader    ID="ucPreloader" ClientIDMode="Static"   runat="server" />
                </ProgressTemplate>
            </asp:UpdateProgress>
       
            <asp:Button runat="server" ID="btnWithoutPostBackTrigger" Text="Button without PostBackTrigger " BackColor="#006600" BorderStyle="Solid" BorderColor="#003300" ForeColor="White"/>
            <asp:Button runat="server" ID="btnWithPostBackTrigger" Text="Button with PostBackTrigger" BackColor="#CC0000" BorderStyle="Solid"  BorderColor="Maroon" ForeColor="White" />
          
        </ContentTemplate>
       
    </asp:UpdatePanel>
</asp:Content>

The code of the Preloader.ascx used to show progress info:
<%--A simple Div that shows us "Loading" message.--%>
<div style="top:150px; width:100%; left:0px; display:block;position:fixed; z-index:2000;" align="center" >
    <table style=" width:600px; height:200px; z-index:2002; background-color:#f9f9f9; border-style:solid; border-color:Grey; ">
        <tr>
            <td valign="middle" align="center">
                <h1 style=" color:Navy">Loading: 5000 milliseconds...</h1>
            </td>
        </tr>     
    </table>
</div>

So, if we click this button with a full PostBack action - we don't see any Progress. If we click the button without the full PostBack action - we see this progress information. But it is not friendly for user, because in one time he sees progress info, in another time he doesn't see it. It would be much better if user has ability to see progress information for each situation.

Investigation
There are many ways to solve this situation. But I select simplest way, as for me. And it is emulation of the showing of the progress info for Update Panel.

Solution 
The idea – to run JavaScript code by clicking our FullPostBack button. In any cases this code will be runned and will be executed before a moment when request of our page will be send to server and will be back.  We click button – and by JavaScript shows ProgressInfo. And until  request don’t return from the server – we see our ProgressInfo. Also we don’t need to think how to hide our ProgressInfo, because when our request returns from server – we will have reRander of our page and it will hide our ProgressInfo automatically.

Code in aspx file…
<div id="divPreloader" style="visibility:hidden;">
      <uc1:Preloader    ID="ucPre"  runat="server" />
</div>

Add this code above somewhere outside of the UpdatePanel.  The purpose of this code – to show  our progressinfo for our  FullPostBack. I placed it  above UpdatePanel. We will find this div by JavaScript and will show it. Yes, if you want you can find Preloader that is used by UpdatePanel inside. But I  prefer to have separate div for this.

And add OnClientClick="ShowProgress('divPreloader')" to our btnWithPostBackTrigger. ShowProgress – it is our JavaScript function that will show what we need.

Code in .vb file
Private Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        Dim PageLoadedHandlerScript As String = " function getObject (sId) { if(!sId) return null; else if (document.all && document.all[sId])  return document.all[sId];  else if (document.getElementById)  return document.getElementById(sId); else return null;}" _
         & " function ShowProgress(sId) { var dP = getObject(sId); if (dP != null) { dP.style.visibility = 'visible'; } }"
        Page.ClientScript.RegisterClientScriptBlock(Me.GetType, "getObjectScript", PageLoadedHandlerScript, True)
        btnWithPostBackTrigger.OnClientClick = "ShowProgress('divPreloader')"
End Sub

In this code we register our JavaScript on the page. There are two functions – the first function finds DOM element by id or name. The second function is our ShowProgress function that is used by btnWithPostBackTrigger. You can use your own JavaScript and jQuery if you need. 

That’s all. Hope it will help you.
to sources >>

Wednesday, February 22, 2012

The Safari’s and Chrome’s problems with Report Viewer 2010 + UpdatePanel + SharePoint 2010 or Uncaught Sys.ScriptLoadFailedException: Sys.ScriptLoadFailedException: The script '.....' could not be loaded. Uncaught TypeError: Cannot read property '_notified' of null.

Initial data
We have one WebPart for the  SharePoint 2010. In this WebPart we have one UpdatePanel. In this UpdatePanel  -  Microsoft Report Viewer 2010 is placed.

Situation
MS Report Viewer  works correct in the IE9.0 and in the Firefox. Report’s data being displayed correctly… But in the Chrome and in the Safari we have nothing.  Well, we see NOT active Report Viewer, without any content.  But if we remove UpadtePanel – all works  good in all browsers. I was trying to reproduce this issue by base website created in the VS2010 (UpdatePanel + Report Viewer) – and again all was good. There was not any problems.  But in the SharePoint2010 – no data in the ReportViewer.

Investigation
By the Chrome Dev Tool (F12) I found that the page had two JavaScript’s errors :
  1. Uncaught Sys.ScriptLoadFailedException: Sys.ScriptLoadFailedException: The script '....' could not be loaded. 
  2. Uncaught TypeError: Cannot read property '_notified' of null
And it was in the MicrosoftAjaxWebForms.js...

Solution
After internet’s revision I found that the same errors often occur in these browsers ( Safary and Chrome) if you use UpdatePanel/AjaxToolkit – all that uses  ScriptManager. MicrosoftAjax in one word… it looks like the problem is in the following - MicrosoftAjaxWebForms.js don't define WebKit browsers correctly
If you add following code on the page - all works correctly :

Sys.Browser.WebKit = {};
if (navigator.userAgent.indexOf('WebKit/') > -1) {
    Sys.Browser.agent = Sys.Browser.WebKit;
    Sys.Browser.version = parseFloat(navigator.userAgent.match(/WebKit\/(\d+(\.\d+)?)/)[1]);
    Sys.Browser.name = 'WebKit';
}

It looks like that correct JavaScript is present for these browsers, but definer is not present.  In any case these rows were solving my problems. But one question still present - why it was in the SharePoint2010 and was not present in the simple website created by VS2010… only one suggestion - different versions of the scripts for these products.

Hope it will help you.