24
Jul/09
0

Comportements Ajax génériques

Le test Ajax prédédent va être modifié afin d’aporter de la généricité dans les comportements, et la possibilité d’avoir plusieurs blocs sur la même page, sans toucher aux modèles.

Pour cela, nous allons travailler principalement sur le javascript.

Tout d’abord, il faut modifier le code HTML pour introduire un bouton d’action (ici, un lien). On ajoutera la ligne suivante dans le fichier priv/templates/views/index.haml :

#main
  %a( href = "/test" ) Add a block

Le style est modifié pour cacher (:display none) le bloc au niveau des modèles. Lorsque la page est chargée, on ne voit que le lien.

On va alors modifier application.js afin de réagir au clic utilisateur :

$(function() {
  $("a").click(function() {
    return false;
  });
});

Le fait de retourner « faux » permet d’invalider le comportement par défaut : lors du clic, plus rien ne se passe.

Il faut alors rajouter les comportements dynamiques :

  • Récupérer l’url de l’action
  • cloner le modèle afin de le réutiliser
  • ajouter le clone au contenu principal et l’afficher
  • charger les données serveur

On utilisera les mécanismes jQuery pour écrire des extensions et permettre une meilleure lisibilité du source. Au lieu de programmer des fonctions, on essaiera de créer des extensions aux objets jQuery - ce qui n’est guère plus compliqué.

Le clonage et autres opérations se fera comme suit :

$.fn.duplicate_to = function(target)
{
  return $(this).clone().show().appendTo(target)
}

Les opérations sont donc très lisibles : on clone l’objet, on l’affiche et on l’ajoute à l’intérieur du tag cible. L’extension peut être utilisée comme ceci :

$("#templates .box").duplicate_to("#main")

Enfin, on charge les données Ajax et on les affiche via Pure. L’extension sera la suivante :

$.fn.render_to = function(target)
{
  $.getJSON($(this).attr("href"), function(context) {
    target.autoRender(context);
  });
}

Ici, on récupère l’URL du composant ayant déclenché l’action (le tag a), puis on initie une requête Ajax sur cette URL et finalement on utilise Pure pour affecter les valeurs aux tags dont les classes CSS correspondent aux clés JSON.

On utilisera cette fonction de cette façon :

$("a").click(function() {
  $(this).render_to($("#templates .box").duplicate_to("#main"));
  return false;
});

On peut alors ajouter autant de blocs que voulu en cliquant sur le lien.

Bien évidemment, ce code est vraiment sommaire et ne s’adaptera pas à toutes les situations, par exemple, si on ajoute une URL inconnue, l’utilisateur n’a pas d’information du problème (comme dans l’image ci dessous, dernier bloc) :

ecr04

Pour réagir aux erreurs, il faut utiliser la fonction $.ajax, comme par exemple :

$.fn.render_to = function(target)
{
  $.ajax({
    url: $(this).attr("href"),
    dataType: "json",
    target: target,
    success: function(context, textStatus) {
      this.target.autoRender(context);
    },
    error: function (xhr, textStatus, errorThrown) {
      this.target.autoRender({title:"An error occurred", content:"Return code : " + xhr.status});
    }
  });
}

Une petite subtilité est présente cependant. On crée une option supplémentaire comme suit :

target: target

En fait, dans les méthodes success et error, le context n’est plus accessible. Donc on ne peut plus référencer le paramètre de fonction target. On le référence donc au sein de la table d’associations de l’objet jQuery.ajax (et comme j’ai peu d’idées pour les noms, il y a redondance :) ).

Maintenant, on a au moins une alerte :

ecr05

Filed under: javascript
Comments (0) Trackbacks (0)

No comments yet.

Leave a comment

No trackbacks yet.