Laurent Duveau
Un AJAX Progress à la GMail
Comment construire un indicateur "chargement en cours" AJAX comme celui de GMail ?
Par Laurent Duveau publié le 11/08/2007 à 11:40, lu 19161 fois,
Pour vos pages aspx, voyons comment réaliser un indicateur "chargement en cours" AJAX à la façon de celui présent dans GMail. C'est à dire fixé dans le coin haut/droit, indépendamment que l'utilisateur scrolle ou redimensionne sa fenêtre de navigateur.
 
Non pas ceclui-là...

Non pas ceclui-là...

 
 
Celui-ci !

Celui-ci !

 
Le framework ASP.NET AJAX dans sa version 1 apporte quelques contrôles serveur dont le fameux UpdatePanel (qui transforme les Postback d'une zone de votre page en appels AJAX asynchrones) et son complément le UpdateProgress qui n'affiche pas comme son nom l'indique une barre de progression mais un simple indicateur visuel de traitement AJAX, ce qui reste quand même bien pratique.
Je me souviens avoir proposé à l'équipe de développement de renommer le contrôle UpdateProgress en UpdateIndicator, mais c'était probablement trop tard...
Afin d'obtenir l'effet désiré (fixé dans le coin haut/droit) une première solution est d'utiliser tout simplement un style CSS sur le contrôle UpdateProgress. Pour cela on ajoute une classe css avec la propriété position:fixed.

Fichier aspx :

<asp:UpdateProgress DynamicLayout="false" ID="UpdateProgress1" runat="server">

    <ProgressTemplate>

        <div class="TopRightFixed">

            <img src="Images/ajax-loader.gif" alt="Loading" />

            Chargement en cours...

        </div>

    </ProgressTemplate>

</asp:UpdateProgress>

Fichier css :

.TopRightFixed 

{

  top: 0px;

  right: 0px;   

  position:fixed;

}

On complète avec une couleur pour le fond, et le tour est joué.
 
Solution avec UpdateProgress et CSS

Solution avec UpdateProgress et CSS

 
On obtient le résultat attendu et on va même améliorer la version GMail avec un petit gif animé ! (voir www.ajaxload.info)
Cette solution est rapide et simple mais pose un problème : la propriété css fixed n'est pas reconnue par IE6.
Il y a bien des solutions à base de CSS hack et expressions (beurk) mais on peut obtenir une meilleure approche plus propre avec la magie de l'AJAX Control Toolkit via le AlwaysVisibleControl!
Voici le résultat final dans IE6 :
 
Version avec un AlwaysVisibleControl

Version avec un AlwaysVisibleControl

 
Voici le code à utiliser :

<asp:UpdatePanel ID="UpdatePanel2" runat="server">

    <ContentTemplate>

        <asp:Button ID="Button2" runat="server" OnClick="Button2_Click" Text="Async Postback" />

        Heure du serveur: <asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>

    </ContentTemplate>

</asp:UpdatePanel>

<asp:UpdateProgress DynamicLayout="false" ID="UpdateProgress2" runat="server">

    <ProgressTemplate>

        <div class="Progress">

            <img src="Images/ajax-loader.gif" alt="Loading" />

            Chargement en cours...

        </div>

    </ProgressTemplate>

</asp:UpdateProgress>

<asp:AlwaysVisibleControlExtender ID="AlwaysVisibleControlExtender1" runat="server"

    TargetControlID="UpdateProgress2" HorizontalSide="Right" VerticalSide="Top" HorizontalOffset="0">

</asp:AlwaysVisibleControlExtender>

et le css associé :

 .Progress

 {

   background-color:#CF4342;

   color:White;

 }

 

.Progress img {

   vertical-align:middle;

   margin:2px;

 }

Comment fonctionne le AlwaysVisibleControl ?
Il utilise JavaScript pour vérifier le navigateur et sa version :
  • Si IE<=6 alors il utilise le css position:absolute et tire avantage du Framework d'Animation pour fixer le div.
  • Sinon (IE>=7, FF2, etc...) il utilise simplement le css position:fixed.
Voici la partie intéressante du code source du AlwaysVisibleControl :

 this._animate = (Sys.Browser.agent == Sys.Browser.InternetExplorer && Sys.Browser.version < 7);

if (this._animate) {

  // Initialize the animations to use the actual properties

  this._animation = new AjaxControlToolkit.Animation.MoveAnimation(

      element, this._scrollEffectDuration, 25, 0, 0, false, 'px');

 

  // Make the control use absolute positioning to hover

  // appropriately and move it to its new home

  element.style.position = 'absolute';

} else {

  // Make the control use fixed positioning to keep it from moving

  // while the content behind it slides around

  element.style.position = 'fixed';

}

Pour finir voici d'autres implémentations de AJAX Progress :
A noter également dans le MSDN de juillet 2007 Dino Esposito a écrit un excellent article pour réaliser un "vrai" AJAX UpdateProgress :
Context-Sensitive Feedback with AJAX

Par la suite dans le MSDN de aout 2007 il a complété son PMF (Progress Monitor Framework) avec un article sur un "vrai" contrôle d'annulation de traitement server side (car le cancel par défaut de l'UpdatePanel ne fait que mettre fin à la communication asynchone) :
Canceling Server Tasks with ASP.NET AJAX

2 articles hautement recommandés pour ceux qui souhaitent pallier auxfaiblesses de ASP.NET AJAX.
 
» Démarrer une discussion