mercredi, juillet 12, 2006

AJAX - Une page Web personnalisable (4/4) : Un peu d'interactivité

Il est temps d'ajouter un peu d'interactivité à cet aggrégateur RSS. L'utilisateur doit pouvoir ajouter un fil RSS, en supprimer, modifier ou mettre à jour le contenu du fil.


L'ensemble des actions doit être géré sans raffraichissement de la fenêtre afin de préserver l'aspect fluide de l'application. Les actions seront transmises via AJAX (suppression d'un fil ou actualisation) mais aussi à travers une boite de dialogue modale si une valeur doit être saisie (ajout et modification d'un fil RSS).

Boite de dialogue modale
Pour la saisie d'information je me suis basé sur la librairie Javascript de subimage que l'on peut trouver sur cette page. Cette librairie a l'avantage de fonctionner sur Internet Explorer, Firefox et Opera (Je n'ai pas testé d'autres navigateurs). En plus d'être simple à intégrer dans le code je trouve de résultat visuel esthétique.
Pour utiliser cette librairie il faut télécharger le package, le décompresser puis ajouter dans la structure de la base Notes les fichiers commons.js, maskBG.png, subModal.js et loading.html, la feuille de style subModal.css et enfin l'image close.gif. Il est à noter que j'ai considéré maskPG.png comme un fichier et non une image car Lotus Notes ne supporte pas encore l'intégration des fichiers PNG dans la librairie d'image.

Pour utiliser cette librairie, il faut d'abord insérer dans l'entête HTML les fichiers javascript ainsi que la feuille de syle :
<head>
<link rel="stylesheet" type="text/css" href="subModal.css" />
<script type="text/javascript" src="common.js"></script>
<script type="text/javascript" src="subModal.js"></script>
</head>

Puis, appeler la fonction showPopWin('URL', largeur, hauteur, fonction_javascript). Par exemple pour ouvrir la boite de dialogue depuis un lien :
<a href="javascript:showPopWin('RSSFeed?openform&action=add', 600, 400, null); ">
Ajouter un fil RSS</a>

Pour fermer la boite de dialogue utiliser la fonction window.top.hidePopWin();
Normalement, si l'on utilise cette dernière fonction avec l'argurment true, la fonction javascript définie dans l'appel de la boite de dialogue s'éxécute.

Supprimer un fil RSS
Pour supprimer un fil RSS, il faut supprimer le document dans la base puis supprimer l'élément sur la page pour ne pas avoir à raffraichir la fenêtre.

Pour supprimer l'élément affiché dans la page nous allons utiliser les fonctions DOM. La fonction sera :
function deleteDiv(fieldname){
var obj;
var old;
if(obj = document.getElementById('NewOrder')){
if( old = document.getElementById(fieldname)){
obj.removeChild(old);
}
}
}

où 'NewOrder' est l'ID de la div contenant tous les fils RSS et fieldname est l'id du bloc à supprimer dans 'NewOrder' passé en paramètre.

Pour supprimer le document Notes on peut utiliser l'URL http://serveur/path/base.nsf/vue/clé?deletedocument
Toujours pour ne pas avoir à raffraichir la fenêtre je lance cette url via Ajax. La fonction de suppression sera donc :
function deleteEntry(fieldname){
var myAjax = new Ajax.Request('RSSByFieldname/' + fieldname + '?deletedocument');
deleteDiv(fieldname)
}

où RSSByFieldname est une vue triée par 'fieldname'.

Le lien permettant de demander la suppression d'un fil sera insérer dans chacun des blocs d'affichage de fil RSS dans la fonction loadRSS, présentée dans le chapitre 3, sous la forme :
<a href="javascript:deleteEntry(\'' + fieldname +'\') ">Supprimer</a>

Actualisation d'un fil RSS
Pour actualiser un fil RSS il suffit de rappeler la fonction loadRSS en spécifiant le fieldname à recharger. Le lien sera lui aussi intégré au niveau de chaque bloc d'affichage de fil RSS depuis la fonction LoadRSS :
<a href="javascript:loadRSS(\'' + url + '\',\'' + fieldname + '\',\''+ nbentrees + '\'); ">Actualiser</a>

Création et modification d'un fil RSS
Pour des raisons de simplification du code la fonction d'ajout et de modification d'un fil RSS sera la même. Pour celà il va falloir :
  1. supprimer le bloc d'affichage du fil RSS s'il existe (dans le cas d'une modification)
  2. créer un nouveau bloc d'affichage du fil RSS sans l'afficher
  3. charger le contenu du fil RSS dans ce bloc
  4. faire apparaitre le bloc
  5. détruire l'objet de gestion du drag &amp; drop qui ne gère pas ce nouveau bloc
  6. reconstruire un nouvel objet de gestion du drag &amp; drop
Soit la fonction :
function addEntry(url, fieldname, nbentrees){
deleteDiv(fieldname);

var newDiv = Builder.node('div',
{id: fieldname, className: 'rss', style: 'display:none;' });
$('NewOrder').appendChild(newDiv);
loadRSS(url, fieldname, nbentrees);
Effect.Appear(newDiv.id);
Sortable.destroy('NewOrder');
Sortable.create('NewOrder',{tag:'div',onUpdate:updateOrder});
}

La fonction Builder.node permet de construire rapidement un nouvel objet DOM. Cette fonction est fournie dans la libraire scriptaculous.
Effect.Appear permet de faire apparaitre le nouveau bloc avec un effet 'd'apparition progressive'. Cette fonction est aussi fournie dans la librairie scriptaculous.

Il ne reste plus qu'à appeler cette fonction depuis un masque Notes affiché dans une boite de dialogue modale.

Masque de création/modification
Le masque doit contenir les champs URL (url du fil RSS) et entrees (le nom maximum de lignes à affichier). De plus, il va aussi falloir pouvoir accèder à la valeur du champ fieldname pour le passer en paramètre de la fonction.

Le problème du champ fieldname est qu'il se base sur l'UniqueID du document Notes. Hors, si celà ne pose pas de problème pour la modification de documents existants, celà est beaucoup plus génant lors de la création d'un document pour ajouter un nouveau fil RSS. L'UniqueID du Document ne sera défini qu'après enregistrement du document. Il doit exister de multiples façons de gérer ce problème.
La solution retenue est de n'appeler la fonction de création du nouveau fil RSS que sur l'évènement unload et si l'URL et un champ fielldname_tmp ayant pour valeur fieldname étaient renseignées. Je l'avoue c'est un peu tiré par les cheveux...
Le masque est défini ainsi :
  • un champ $PublicAccess : texte calculé à la création avec pour formule "1" (celà permet d'autoriser l'accès Public)
  • un champ URL : texte modifiable
  • un champ entrees : nombre modifiable
  • une déclaration HTML de champ field_tmp avec pour valeur le champ fieldname de type texte calculé avec pour formule @If(@IsNewDoc; ""; "liste_" + @Text(@DocumentUniqueID))
La déclaration HTML est : [<input type="hidden" value="<Champ fieldname>" name="fieldname_tmp">]
On peut soit déclarer le contenu entre crochets comme ci-dessus ou déclarer la ligne en HTML relais.


On ajoute trois boutons à ce masque
  • Fermer (masquer si : @IsNewDoc) avec pour formule Web/Javascript :
    window.top.hidePopWin();
  • Enregistrer avec pour formule :
    @Command([FileSave]);
    FIELD fieldname := "liste_" + @Text(@DocumentUniqueID);
    @Command([FileSave])
  • Annuler avec pour formule Web/Javascript :
    document.forms[0].fieldname_tmp.value = "";
    window.top.hidePopWin();
Et enfin, à l'évènement unLoad du masque :
if(document.forms[0].URL.value!='' & document.forms[0].fieldname_tmp.value!=''){
window.top.hidePopWin();
window.top.addEntry(document.forms[0].URL.value,
document.forms[0].fieldname_tmp.value,document.forms[0].entrees.value);
}

On peut constater que le bouton Annuler vide le champ fieldname_tmp ce qui permet de ne pas exécuter l'appel à la fonction d'ajout/modification.

Téléchargement et démonstration en ligne

Vous pouvez télécharger une base Notes permettant de tester toutes les fonctionnalités de cet aggrégateur RSS AJAX. La base contient en plus un module de création de flux RSS afin de pouvoir tester l'application. N'oubliez pas de signer la structure et de définir la LCA.

Vous pouvez aussi tester en ligne ce module en version bridée, les actions sont visibles mais pas enregistrées dans la base. Si vous recharger la fenêtre vous reviendrez sur l'environnement de base. De plus l'ajout de nouveaux fils RSS est inactif.

1 Commentaires:

Blogger domlike dit...

Génial cette boite de dialogue modale !

Lotus Notes ne supporte pas encore l'intégration des fichiers PNG dans la librairie d'image
Si si il supporte il faut seulement lui forcer un peu la main. Si tu tapes le nom du fichier avec l'extension .png, il l'intègre bien.

mardi, juillet 18, 2006 10:17:00 PM  

Enregistrer un commentaire

Lien vers ce message:

Créer un lien

<< Home

Rechercher sur ce blog
Effacer résultat