Blog de Julien Dollon (MVP)

Consultant / Formateur .NET

Julien Dollon

Consultant/formateur .NET pour I'FORM/Exakis et Full Professor SUPINFO.

Responsable de la communauté Dotnet-France ainsi que nommé Most Valuable Professional, je participe activement à la communauté Microsoft.

 

 

Mon CV de Consultant/Formateur .NET

Mon Transcript de Formateur .NET

 


 
 
 
 
Official INETA Logo
 
IForm

[jQuery] Consommer un service Astoria avec jQuery

jquery1

jQuery est un framework JavaScript open source (GNU/GPL) qui sera intégré de base dans Visual Studio 2010.

Ce fut l’occasion pour moi de m’y pencher à l’aide des articles de Davy Pallu.

La communauté autour de jQuery est assez impressionante, d’autant plus que cette technologie est entierement orientée plug in. Léger, cross-browsers et facile d’utilisation, jQuery a su me séduire en remplacement de mes vieux scripts JavaScript.

Pour l’installer il vous suffit d’ajouter à votre projet web actuel le fichier vsdoc de jQuery. Celui ci est téléchargeable sur jquery.com.

La version actuel est la 1.3.2 et le plug in de production fait la taille de 19ko.

Dans cet article, je vais utiliser jQuery pour l’interface graphique mais également pour mes requêtes AJAX afin d’exploiter ADO.NET Data Services (Astoria) qui fournit une serialisation JSON.

Pour plus d’information sur la création du service type Astoria, référez vous à ce billet.

Pour les sources de ce projet, vous les trouverez ici.

Après avoir créé mon service Astoria et ma base de données contenant une table Clients et SecteurActivites je commence le jQuery:

jquery2

Création du menu

Le menu en jQuery doit proposer la liste des tables proposées par le service. Dans un premier temps je vais concevoir le script jQuery afin d’avoir un semblant de menu animé.

Le css du menu (Menu.css):

   1: body{
   2:     font-family:"Lucida Grande", arial, sans-serif;
   3: }
   4: li{
   5:     width:100px;
   6:     height:50px;
   7:     color:#191919;
   8:     text-align:right;
   9:     cursor:pointer;
  10:     overflow:hidden;
  11:     background:#0292C0;
  12: }
  13: a{
  14:     color:#FFF;
  15:     text-decoration:none;
  16: }
  17: .subtext{
  18:     padding-top:2px;
  19: }

Le fichier javascript Menu.js en jQuery:

   1: $(document).ready(function() {
   2:     $("li").hover(function() {
   3:         $(this).stop().animate(
   4:             { width: '150px'
   5:             },
   6:             {
   7:                 duration: 400,
   8:                 easing: 'easeOutBounce'
   9:             })
  10:     },
  11:     function() {
  12:         $(this).stop().animate(
  13:             { width: '100px' },
  14:             { 
  15:                 duration: 400,
  16:                 easing: 'easeOutBounce'
  17:             })
  18:         })
  19: });

La méthode ready() correspond en quelque sorte au PageLoad de mon document. J’utilise alors la méthode hover() qui permet de gérer le mouse enter / leave.

Dès que la souris survole un élément de type “li” je modifie sa taille en utilisant l’easing.

L’easing rendra mon animation plus “vivante” et moins linéaire. L’utilisation de l’easing passe par l’ajout d’un plugin appelé jquery.easing.1.3.js et téléchargeable ici.

Au niveau du fichier html j’ajoute les références aux fichiers JS et CSS:

   1: <link type="text/css" rel="stylesheet" href="Menu.css"/>
   2: <script src="jquery-1.3.2.js" type="text/javascript" />
   3: <script src="jquery.easing.1.3.js" type="text/javascript" />
   4: <script src="Menu.js" type="text/javascript" />

Et j’ajoute des données en dur pour voir le résultat de mon menu:

   1: <ul>
   2:         <li>
   3:             <p><a href="#">Table 1</a></p>
   4:         </li>
   5:         <li>
   6:             <p><a href="#">Table 2</a></p>
   7:         </li>
   8: </ul>

menujquery

Il me faut maintenant me connecter au service Astoria et génèrer dynamiquement le menu.

Pour cela je mets en place l’utilisation de la sérialisation JSON avec les méthodes AJAX intégrées dans jQuery:

   1: <script type="text/javascript">
   2:     function displayTable(table) {
   3:         $("#ul_tables")
   4:                       .append("<li><p><a href=\"#\">" 
   5:                            + table + "</a></p></li>");
   6:     }
   7:     
   8:     function getTables() {
   9:         $.ajax({
  10:             type: "GET",
  11:             url: "WebDataService.svc",
  12:             data: "{}",
  13:             contentType: "application/json; charset=utf-8",
  14:             dataType: "json",
  15:             success: function(data) {
  16:                 for (var i in data.d) {
  17:                     for (var n in data.d[i]) {
  18:                         displayTable(data.d[i][n]);
  19:                     }
  20:                 }
  21:             },
  22:             error: function(xhr) {
  23:                 alert(xhr.responseText);
  24:             }
  25:         });
  26:  
  27:         return false;
  28:     }
  29: </script>

et je crée un bouton HTML qui chargera mon menu:

   1: <button onclick="return getTables();">Get Tables</button>

L’un des inconvénients de cette solution est que mon menu est certes bien rempli avec les tables mais jQuery ne capte pas la méthode “hover” puisqu’il a été modifié à la volée.

jquerymenuajax Pour cela, il existe la méthode live() qui saura prendre en compte les ajouts d’éléments dans mon menu.

Menu.js devient comme ceci:

   1: $(document).ready(function() {
   2:     $("li").live("mouseover", function() {
   3:         $(this).stop().animate(
   4:             { width: '150px'
   5:             },
   6:             {
   7:                 duration: 400,
   8:                 easing: 'easeOutBounce'
   9:             });
  10:         })
  11:  
  12:         $("li").live("mouseout", function() {
  13:             $(this).stop().animate(
  14:             { width: '100px'
  15:             },
  16:             {
  17:                 duration: 400,
  18:                 easing: 'easeOutBounce'
  19:             });
  20:         })
  21: });

Nous pouvons agrémenter notre solution d’une progressbar se déclenchant pendant que la requête AJAX s’effectue.

Après avoir généré un GIF sur http://www.ajaxload.info, je m’abonne aux événements ajaxStart et ajaxStop de mon document.

J’utilise le plug in SimpleModal disponible ici.

   1: $(document).ajaxStart(function() {
   2:     $.modal("<div><img src=\"Images/ajax-loader.gif\" /></div>", 
   3:         { onOpen: function(dialog) {
   4:         dialog.overlay.fadeIn('fast', function() {
   5:             dialog.data.hide();
   6:             dialog.container.fadeIn('fast', function() {
   7:                 dialog.data.slideDown('fast');
   8:             });
   9:         });
  10:     } 
  11:     });
  12: });
  13: $(document).ajaxStop(function() {
  14:     $.modal.close();
  15: });

Affichage des données contenus dans les tables

L’affichage du contenu d’une table se fera à l’aide d’une modal popup. Pour changer de technique, je mettrai en application le plug in jQueryUI.

jQueryUI est un peu l’Ajax Control Toolkit des développeurs ASP.NET. Il fournit de nombreux effets, thèmes, contrôles réutilisable…

Après l’avoir téléchargé sur le site officiel www.jqueryui.com j’ajoute à ma page les liens vers les CSS et fichiers javascripts:

   1: <link type="text/css" href="css/ui-lightness/jquery-ui-1.7.2.custom.css" 
   2: rel="stylesheet" />    
   3: <script src="Scripts/jquery-ui-1.7.2.custom.min.js" type="text/javascript" />

Le skin par défaut de jQueryUI est orange, j’en profite pour modifier Menu.css afin d’avoir une IHM globalement orange (et moche :))

Je capture le clic sur mon menu et appel la méthode getTable qui se chargera d’afficher les données:

   1: $("li").live("click", function($e) {
   2:     $e.preventDefault();
   3:     return getTable($(this).attr("href"));
   4: })

La méthode getTable se connecte grâce à l’AJAX à mon service pour lire les données au format JSON.

   1: function getTable($tableName) {
   2:     $.ajax({
   3:         type: "GET",
   4:         url: "WebDataService.svc/" + $tableName,
   5:         data: "{}",
   6:         contentType: "application/json; charset=utf-8",
   7:         dataType: "json",
   8:         success: function(data) {
   9:             for (var i in data.d) {
  10:                 for (var n in data.d[i]) {
  11:                     //Mise à jours des données içi
  12:                 }
  13:             }
  14:             $("#dialog").dialog('open');
  15:         },
  16:         error: function(xhr) {
  17:             alert(xhr.responseText);
  18:         }
  19:     });
  20:  
  21:     return false;
  22: }

Voici le résultat:

jquerytable1 

Il me manque l’implémentation de l’affichage des données. Le problème est que nous recevons bien les données mais il nous faut d’abord afficher le nom des colonnes.

Le nom des colonnes sont représentées par des propriétés de l’objet créée à la volé:

jquerycolonne

Pour cela je vais utiliser la réflexion comme en C#.

function GetProperties(obj) {
    var props = new Array();
    for (var s in obj) {
        if (typeof (obj[s]) != "function") {
            props[props.length] = s;
        }
    }
    return props;
};
function getTable($tableName) {
    $.ajax({
        type: "GET",
        url: "http://localhost:2935/WebDataService.svc/" 
											+ $tableName,
        data: "{}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(data) {
            var corp = "<tbody>";
            for (var i in data.d) {
                corp += "<tr>";
                //Si c'est la première boucle -> Récupération des noms de colonnes par reflexion
                if (i == 0) {
                    var entete = "<thead><tr class=\"ui-widget-header\">";
                    var props = GetProperties(data.d[i]);
                    for (var z in props) {
                        entete += "<th>" + props[z] + "</th>";
                        //Value: data.d[i][props[i]]
                    }
                    entete += "</tr></thead>";
                    $("#tables").append(entete);
                }
                for (var n in data.d[i]) {
                    //Mise à jours des données içi
                    
                    corp += "<td>";
                    corp += data.d[i][n];
                    corp += "</td>";
                }
                corp += "</tr>";
            }
            corp += "<tbody>";
            $("#tables").append(corp);
            $("#dialog").dialog('open');
        },
        error: function(xhr) {
            alert(xhr.responseText);
        }
    });

    return false;
}

Résultat:

jquerycolonne2

Pour le reste des opérations (CRUD) il suffit de modifier le type de la requête (Par exemple POST ou DELETE) à ce niveau:

 $.ajax({
        type: "GET",
        url: "http://localhost:2935/WebDataService.svc",
        data: "{}",
        contentType: "application/json; charset=utf-8",
Posted: Oct 07 2009, 02:10 by juliend | Comments (3) RSS comment feed |
  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Filed under: jQuery | .NET | Général

Comments

minsou said:

Bonjour, vos sources ne fonctionnent pas il faut apparemment visual studio 2010 ...

# October 07 2009, 23:10

minsou said:

Il faut supprimé cette ligne du fichier csproj :   <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />

# October 07 2009, 23:13

juliend said:

Bonjour minsou,
Effectivement je l'ai réalisé avec VS2010 ;) Merci d'avoir relevé le problème.

# October 08 2009, 00:13

Add comment




  Country flag

biuquote
  • Comment
  • Preview
Loading

captcha

*