por Ing. Juan Pablo Ibañez
http://ing.juanpablo.googlepages.com
Uno de los controles mas usados de la librería AJAX de Microsoft (ajax.asp.net) es el control UpdatePanel. Este control nos permite hacer un postback parcial de la página y solamente modificar una sección de la misma sin tener que recargar completamente la página. Cuando este postback parcial demora mucho, es conveniente mostrarle el estado al usuario, generalmente se muestra un mensaje como por ejemplo "cargando...", "loading...", "procesando...", etc.
La librería AJAX de Microsoft nos permite hacer esto mediante el control UpdateProgress. Usar este control es sumamente fácil, lo que debemos hacer es definir en un div, por ejemplo, el templete que deseamos que se muestre cuando se está realizando un postback asíncrono.
Un ejemplo de UpdateProgress seria:
<asp:UpdateProgress ID="UpdateProgress1" runat="server">
<ProgressTemplate>
An update is in progress...
</ProgressTemplate>
</asp:UpdateProgress>
Cuando algunos de los UpdatePanel que tenga nuestra página .aspx haga un postback parcial, aparecerá el UpdateProgress y el usuario sabrá que debe esperar hasta que se actualice la parte de la página que está englobada en el UpdatePanel.
Hasta aquí es todo muy simple, el problema surge generalmente cuando el usuario no espera que se actualice la página y hace click nuevamente en el botón, o en otros botones y genera sucesivos postback parciales de la página. Para evitar esto existen varias soluciones:
- Deshabilitar del lado del cliente por Javascript todos los controles que hagan postback al servidor hasta que finalice la actualización parcial de la página. El problema es que requiere mucho código Javascript para hacerlo. Si agregamos un control nuevo, tenemos que modificar nuestra rutina para contemplar este nuevo control.
- Otra opción, que es la razón de este artículo es utilizar un ModalPopup que cuando presionemos cualquier control que haga un postaback parcial aparezca bloqueando toda posibilidad de que el usuario haga un click en otro control. La ventaja de esta solución es que podemos implementarla de manera tal que sea independiente de la cantidad de controles que tenga nuestra página y de cantidad de páginas que tenga nuestro sitio, etc, etc, etc.
Los elementos que debemos utilizar en esta segunda opción son:
- MasterPage.
- ModalPopup.
- Sys.WebForms.PageRequestManager.
La idea es armar un esquema que no necesite ser replicada en cada una de los webforms que creemos en nuestra aplicación, es por eso que utilizaremos una MasterPage. Es decir en nuestra MasterPage tendremos definido el ModalPopup y el Javascript necesario para hacerlo aparecer, cuando se lance una petición de postback parcial por cualquiera de los controles definidos en cualquiera de nuestros webforms que tengan seteada nuestra MasterPage y también ocultar el ModalPopup cuando la actualización esté terminada.
Muestra MasterPage podría ser:
<%@ Master Language="C#" CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<%-- Código Javascript --%>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server"
EnableScriptGlobalization="True"
EnableScriptLocalization="True">
</asp:ScriptManager>
ESTA ES UNA MASTER PAGE
<asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
</asp:contentplaceholder>
</div>
<%-- ModalPopup --%>
</form>
</body>
</html>
Una vez que tenemos nuestra MasterPage lo que debemos definir en esta es el ModalPopup. Un ejemplo de ModalPopup sería:
<asp:LinkButton ID="LinkButton1" runat="server" Visible="true"/>
<asp:Panel ID="Panel" runat="server" Style="display: none">
<table class="modalPopUp" border="0" cellpadding="0" cellspacing="0">
<tr class="modalPopUpTopRow">
<td valign="middle">
<img src="images/ajax-loader.gif" alt="procesando..." />
</td>
</tr>
<tr>
<td align="center">
Procesando...
</td>
</tr>
</table>
</asp:Panel>
<cc1:ModalPopupExtender ID="ModalPopupExtender" runat="server"
BehaviorID="programmaticModalPopupBehavior"
TargetControlID="LinkButton1"
PopupControlID="Panel"
BackgroundCssClass="modalBackground"/>
Basicamente es ModalPopup tiene un gif animado y una leyenda de "Procesando...". O sea que cuando algún control haga una petición de postback parcial aparecerá este ModalPopup indicando que debe esperar a que termine la actualización de la página evitando que el usuario pueda hacer click en cualquiera de los controles.
Lo que falta ahora es el código Javascript que hacer aparecer y desaparecer el ModalPopup cada vez que comienza y finaliza un request.
Para esto haremos uso del objeto PageRequestManager y le añadiremos 2 funciones una para el evento beginRequest y otro para el evento endRequest.
Estas funciones lo que hacen es buscar el BehaviorID del ModalPopup y una vez que obtenemos la referencia al ModalPopup llamar al método hide() o show() del ModalPopUp.
<script type="text/javascript">
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(
function (sender, arg){
var modalPopupBehavior = $find('programmaticModalPopupBehavior');
modalPopupBehavior.hide();
}
);
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(
function (sender, args) {
var modalPopupBehavior = $find('programmaticModalPopupBehavior');
modalPopupBehavior.show();
}
);
</script>
2 comments:
Saludos, pues estoy tratando de hacer algo parecido pero me marca un error al usar el Sys, parece que es un error del ajax, estoy trabajando con vs 2008, saludos
hola, mira en esta pagina, también describe un método de como hacer lo mismo:
http://systemdeveloperpy.blogspot.com/2014/02/disable-controls-on-page-pending.html
Post a Comment