Nicolas Moyère
Utilisation de jQuery avec ASP.NET MVC
Développer une IHM à page unique avec ASP.NET MVC et jQuery
Par Nicolas Moyère publié le 30/06/2008 à 10:28, lu 1679 fois, 9 pages
 5 | Saisie d'un nouveau message
Pour cette étape, nous voulons uniquement mettre à jour la zone d'action de l'interface avec le champ de saisie du message.

Pour cela il nous faut trois choses :
  • Le clic sur le lien pour envoyer un message ne doit pas déclencher de navigation, mais doit quand même appeler notre contrôleur.
  • Concernant le contrôleur, l'ActionResult utilisé doit contenir uniquement le HTML de la zone de saisie.
  • Le navigateur doit remplacer le contenu de la zone d'action par le HTML reçu.
Le premier et le dernier point nécessitent du Javascript. La bibliothèque jQuery fournit toutes les briques dont nous avons besoin.
L'idée est d'utiliser jQuery pour bloquer le lien, déclencher un appel AJAX sur le clic puis manipuler le DOM de la page pour y insérer le HTML retourné par le contrôleur.

Le deuxième point est le plus simple. Si nous voulons transmettre uniquement la zone de saisie, il suffit de créer une nouvelle page ASP avec seulement cette partie.

Commençons par implémenter l'action New de MessagesControlleur que nous avions laissée vide :

public ActionResult New(string id)

{

    // On commence l'écriture en partant d'un

    // message vide.

    // On n'actualise que les champs de saisie

    // de New.ascx.

    ViewData.Model = id;

 

    return View();

}

Comme la méthode View est utilisée sans paramètres, MVC cherche une page ayant le nom de l'action en cours dans le répertoire des vues du contrôleur. Dans notre cas, le fichier s'appelle Views/Messages/New.ascx :

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="New.ascx.cs" Inherits="Messenger.Views.Messages.New" %>

 

<form method="post" action="<%= Url.Action("Send", new { id = ViewData.Model } ) %>">

    <textarea name="messagetext" cols="28" rows="3"></textarea>

    <br />

    <%= Html.SubmitButton("send", "Send") %>

</form>

Cette vue contient uniquement la partie à afficher dans la zone d'action : un formulaire déclenchant l'appel à l'action Send de MessagesController.

Passons à la partie Javascript.

jQuery est une bibliothèque Javascript très simple à utiliser. Ses créateurs essayent de capitaliser sur nos connaissances de HTML et de CSS pour simplifier leur API.
Je vous résume rapidement le fonctionnement de jQuery. Il y a généralement deux étapes :
  • La sélection des parties de la page à manipuler. La sélection s'effectue en appelant la fonction $(sélecteur) ou la fonction jQuery(sélecteur) en lui passant un sélecteur CSS en paramètre.
    Par exemple $('a') retourne toutes les balises a du document.$('#panel a') retourne toutes les balises a à l'intérieur de l'élément ayant comme identifiant panel.
  • Appel d'une fonction sur chaque élément sélectionné.
    La fonction html(texte) remplace le contenu des éléments sélectionnés par celui en paramètre.
    La fonction click(fonction) intercepte l'évènement onclick.
    L'appel $('a').html('ceci est un lien') remplace le texte de tous les liens de la page.
jQuery propose aussi quelques fonctions qui ne sont pas liées à un noeud du document comme la fonction ajax(url).

Nous allons écrire une extension de jQuery chargée d'intercepter le clic sur le lien, de faire l'appel au contrôleur puis de mettre à jour la page.

Le code de l'extension est le suivant :

; (function() {

 

var successFunction = function (data, textStatus) {

    jQuery('#panel').html(data.toString());

};

var errorFunction = function(XMLHttpRequest, textStatus, errorThrown) {

    // Make sure to display the server side error page

    if (XMLHttpRequest !== undefined) {

        jQuery('body').html(XMLHttpRequest.responseText);

        return;

    }

    if (textStatus !== undefined) {

        alert(textStatus);

        return;

    }

    if (errorThrown !== undefined) {

        alert(errorThrown);

        return;

    }

};

 

jQuery.fn.ajaxify = function() {

    return jQuery(this).each(function() {

            // AJAX links

            return jQuery(this).click(function() {

                try {

                    jQuery.ajax({url:this.href, type:'get', dataType:'html',

                                cache:false, success:successFunction,

                                error:errorFunction });

                } catch(e) {

                    alert(e);

                }

                return false;

            });

    });

};

 

})();

La fonction successFunction reçoit la réponse du contrôleur. Elle utilise jQuery pour modifier le DOM de la page. Pour l'instant, l'identifiant DOM de la zone d'action est utilisé en dur.

La gestion des erreurs doit être soignée. Elle est prise en compte par errorFunction. Par exemple, si une exception coté serveur est interceptée alors le détail du problème est affiché dans le navigateur.

Le coeur de l'extension jQuery est la méthode ajaxify. Pour chacun des éléments gérés par jQuery, elle intercepte l'évènement onclick et le remplace par un appel AJAX.

Pour recoller tous les morceaux, il nous reste à inclure notre code Javascript dans la page d'accueil puis à ajaxifier les liens du menu.Il suffit d'ajouter les appels de jQuery suivants :

$(document).ready(function() { $('#actions a').ajaxify(); });

Ce code indique à jQuery d'exécuter notre extension sur tous les liens du menu quand la page a terminé son chargement.

Maintenant, les étapes suivantes se déroulent durant l'exécution de l'application :
  • Au démarrage, jQuery détourne les liens du menu vers notre extension.
  • Lors du clic sur Send Msg, notre extension utilise l'URL du lien pour appeler l'action New de MessagesController.
  • Le contrôleur retourne un ViewResult pour New.ascx.
  • L'exécution du ViewResult renvoie tout le contenu de News.ascx.
  • Enfin, l'extension jQuery change le contenu du div panel par le HTML généré par News.ascx.
À la fin de cette étape, nous pouvons remplacer une partie de notre interface par une page ASPX ou un contrôle ASCX complet.
 
» Démarrer une discussion