Imaginons le cas pratique suivant. J'arrive sur une page avec une liste d'items et des boutons de pagination (précédent - 1 - 2 -3 - suivant). Je clique sur suivant, et seul la liste des items est chargée via ajax. Je clique 3 fois sur suivant, je suis donc à 4 chargements de listes, et je trouve enfin ce que je cherche. Sur l'item en question, un lien externe m'envoie vers une nouvelle page. Zut, c'était pas ça. Je clique sur le bouton précédent de mon navigateur… Arf… Me revoilà à la première page de pagination de ma liste d'item. Heureusement que je me souviens que j'était à la 4° page, sinon, j'aurais du me retaper tout les clics sur suivant jusqu'à reconnaitre la page où j'étais.
Pour éviter ceci, je vous propose une solution toute simple. Le concept est de placer des paramètres en tant qu'ancre dans l'url :
Nous arrivons sur la page principale, nous sommes à l'adresse :
http://www.monsiteenajax.com/liste.html
Je clique sur suivant, l'adresse ne change pas. C'est ici qu'il faut agir. Lors du clic, je vais ajouter une ancre à l'url avec mes paramètres pour me retrouver avec une url de ce style :
http://www.monsiteenajax.com/liste.html#page-2
Pour ce faire, il suffit de changer la valeur de window.location. Voici une fonction qui permet de changer cette valeur :
var changeAnchor = function(anchor)
{
// Si l'url possède déjà une ancre
if (window.location.href.match(new RegExp('#.*$')))
{
window.location = window.location.href.replace(
new RegExp('#.*$'),
'#' + anchor
);
}
// Sinon, il suffit de l'ajouter à la fin
else
{
window.location = window.location.href + "#" + anchor
}
return window.location;
}
Donc, lors de l'évenement qui va déclencher la requete ajax et l'affichage de la deuxième page de la liste, je fais un petit changeAnchor('page-2') afin de changer mon ancre et garder en mémoire que je suis sur la pagination numéro 2.
Ainsi, si je change de page, puis que je clique sur Précédent, ça sera l'url http://www.monsiteenajax.com/liste.html#page-2 qui sera chargée.
Ne reste plus qu'à exploiter cette fonction. C'est encore tout simple. Implémentez cette fonction :
var getAnchor = function()
{
return window.location.href.match(
new RegExp('#.*$')
);
}
Il ne reste plus qu'à l'appeler au load de la page, et de faire les actions relatives à ce qu'elle renvoit.
Reprenons notre cas. Je clique sur le lien pour avoir la pagination suivante. Cela va appeler une fonction qui va charger la liste et à la fin, elle va faire un changeAnchor('page-2').
Sur le onload de la page, je met un switch sur le getAnchor pour effectuer les actions relative. Donc, là, si mon anchor contient page, il faudra afficher la page dont le numéro suit :
window.onload = function()
{
// Je récupère l'ancre et la splite sur le '-' car
// j'ai décidé de séparer mes paramètres par des '-'
var startParams = getAnchor()page.split('-');
// Je teste le premier paramètre
switch (startParams[0])
{
case 'page':
// Je suis dans le cas de la pagination
// Si le deuxième paramètre est setté
if (startParams[1])
{
// J'apelle ma méthode d'affichage de page
// avec le paramètre adéquat
displayPage(
startParams[1]
);
}
break;
// Je peux imaginer un autre cas
case 'autrecas':
doSomething();
break;
}
}
Et voilà. Si je quitte cette page, puis que j'y reviens en consultant mon historique, je reviendrais à l'affichage ajax correspondant. Autre bonus, à chaque fois que l'on change l'ancre via changeAnchor(), c'est une nouvelle entrée dans l'historique du navigateur qui se crée. Donc, on peut réellement utiliser les boutons de la navigation comme pour un site traditionnel.
Un autre avantage très important, c'est que le site redevient bookmarkable. L'utilisateur peut sans problème mettre en signet une page modifiée par ajax.
Si vous avez des remarques ou des améliorations à proposer, n'hésitez pas 
EDIT : Voici un exemple pratique.
Commentaires
C'est diablement compliqué, j'ai rien compris, il fait vraiment trop chaud pour ce genre de chose...
J'aime bien, mais c'est trop compliqué.
Le mieux à mon avis, est de ne pas faire d'ajax pour ce genre d'utilisation. C'est moins fun, mais beaucoup plus pratique.
lol je suis d'accord avec toi yellow, mais du coup, c'est pas web2.0 fashion stylé… :p
Et alors tth ! Tu mets ton cerveau en pause le week end ? Ou tu as bu trop de binouse ?
Imaginant qu'un client vous demande plutot exige un site web full ajax ... alors là je suis sur et certain que vous allez lire et lire attentivement cet article... je trouve que c'est trés bonne idée la solution que tu apporte au problèmatique suivant/precedent
Merci .....
Et il voudra aussi des graphismes "MIR couleur", le client. Faudrait tous les virer les clients. C'est comme le singleton, c'est le mal absolu...
Et wé tth… Le client say le mal. Mais le client nous permet de manger. Dur paradoxe
Salut, très bonne explication
Par contre peut être à completer car tu utilise une fonction DisplayPage que tu ne détails pas ici.
Ce serait bien de la précisez
Merci
Le displayPage() peut être n'importe quoi : une requête ajax qui va chercher du contenu et l'insère à coup de innerHTML, un style.display = block sur un div déjà chargé, un simple alert(), etc… Quand j'aurais récupéré le net chez moi, je pourrais finir ma classe générique qui permet d'avoir une pagination à coup de requêtes ajax, et j'en dirais un peu plus…
Merci pour l'astuce, je suis vraiment intéressé, mais malheureusement ça ne marche pas pour IE (6 ou 7) : les différentes ancres ne modifient pas l'historique. Il y a-t-il une autre astuce pour que cela fonctionne ?
En tout cas merci beaucoup.
J'y travaille… Enfin du moins j'y travaillerais quand j'aurais le net… :p Comme dit plus haut, je proposerais à terme une classe générique sous licence GPL pour faire tout ça facilement.
Browser History Manager:
http://developer.yahoo.com/yui/exam...
Arf, ça servait à ça cette classe de YUI… J'avais pas eu l'occasion de la regarder de près… j'aurais du :/ Merci pour l'info
Ajouter un commentaire
Abonnement aux commentaires
S'abonner pour recevoir les commentaires suivants par email
Fil des commentaires de ce billet