Ajax Update Progress: Modified

Problem:

Depending on your design, it may or may not work to have your atlas progress rendering inline with your other content.  This is actually kind of a pain.  My situation included a gridview being rendered that may require the user to scroll, clicking a paging link at the bottom.   Clicking this link triggers the update progress template at the TOP of the page - But does almost nothing to inform the user who has now scrolled down and doesn't see it.

We need a way to inform the user that an Ajax panel is getting data from the server, and is actually doing anything.  Surprisingly enough, the "page flash" that we all hated in a standard browser application, did serve as instant user feedback - where as Ajax update panes leave the web page drooling and blinking at the user.  In some cases they may not even be aware that data has changed or updated. 

Solution:

Enter JavaScript - yea I know what you're saying.  Your application is managed, and you don't want to clutter it up with JavaScript.  Believe me, you are preaching to the choir here, but it's pretty painless. 

Concept:  We are going to declare a DIV inside the progress template.  We are then going to set the div inside the panel to a CSS class that positions it absolutely.  Then with a little JavaScript we are going to keep it on the mouse cursor, so that when it appears - it's in a position that will give feedback to the user. 

Ok - so lets get started eh?

For this example, I'm going to return a DateTime string, and set it to the label in my page.  I'm going to do this in some code that forces a delay so we can see the update Progress template work. 

Go ahead and get your page setup like this to get us started. 

You can get some free Ajax Update type animated GIFS from this site. I went ahead and grabbed the Roller.gif for this example.

http://mentalized.net/activity-indicators/

<div>    
    <asp:ScriptManager ID="ScriptManager1" runat="server" />    
    <asp:UpdateProgress ID="UpdateProgress1" runat="server">        
        <ProgressTemplate>            
            <div id="updateDiv" style="position: absolute">                
                <img src="roller.gif" />            
            </div>        
        </ProgressTemplate>    
    </asp:UpdateProgress>    
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">        
        <ContentTemplate>            
            <asp:Label ID="lblDateTime" runat="server" Text="" /><br />            
            <asp:Button ID="btnUpdate" runat="server" Text="Update" />        
        </ContentTemplate>    
    </asp:UpdatePanel>
</div>
 
Protected Sub btnUpdate_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnUpdate.Click    
    'THREAD SLEEP should never be used in production applications    
    System.Threading.Thread.Sleep(4000)    
    lblDateTime.Text = System.DateTime.Now
End Sub

Again, nothing special here.  We simply created a button click event that updates our labels value.  The progress template we setup will kick in as soon as that thread sleep starts ticking.

Go ahead and test your project at this point.  Not very useful to say the least if your page scrolls at all.  Enter JavaScript (our superhero).

JavaScript:

Ok, I wont overly explain this JavaScript.  Usually my requirement is not to understand it, just that it works.  This goes between the Head tags of your page.

<script type="text/javascript" language="javascript">       

var IE = document.all?true:false      
 // If NS -- that is, !IE -- then set up for mouse capture       
if (!IE) document.captureEvents(Event.MOUSEMOVE)       
// Set-up to use getMouseXY function onMouseMove       
document.onmousemove = getMouseXY;       
// Temporary variables to hold mouse x-y pos.s       
var tempX = 0       
var tempY = 0       
// Main function to retrieve mouse x-y pos.s       
function getMouseXY(e) {           
if (IE) { 
// grab the x-y pos.s if browser is IE               
tempX = event.clientX + document.body.scrollLeft              
tempY = event.clientY + document.body.scrollTop           
} 
else 
{  
// grab the x-y pos.s if browser is NS               
tempX = e.pageX              
 tempY = e.pageY      
 }   
// catch possible negative values in NS4 
if (tempX < 0){tempX = 0} if (tempY < 0){tempY = 0}   
// show the position values in the form named Show 
// in the text fields named MouseX and MouseY 
var divToMove = document.getElementById("updateDiv") 
divToMove.style.left = tempX 
divToMove.style.top = tempY return true  
 
</script>

And Wa-lah!  Go ahead and render your page and click the button.  You're progress now stays on your mouse, and gives the user instant feedback that something is going on.  In a follow-up we'll examine two different methods of accomplishing this, that also could be useful. 

Happy Coding.

Bryan Sampica - ASP.NET MVP.

2 Comments

Comments have been disabled for this content.