Intégration DhtmlxGrid dans Application Lotus-Notes Domino

imdomino1LogoDhtmlx

 

Dans un précédent article nous avons vu comment intégrer la Technologie Web2.0 dans nos applications Notes vieillissantes. Nous allons maintenant voir la puissance du Framework "DhtmlxGrid ".

Les sources proviennent de la version gratuite en ligne :

http://dhtmlx.com/docs/download.shtml

L'exemple détaillé dans l'article est disponible via le lien  ci-dessous :

Ex_DHtmlxGrid

Nous verrons plusieurs éléments :

  • Comment retourner une vue XML avec filtres sur chaque colonne.
  • Supprimer, créer, exporter les documents de la vue XML.
  • Editer une colonne avec modification en base

1/ Installez les composants dans base Notes

Tous les éléments de structure sont à copier / coller depuis la base attachée à l'article (Ex_DHtmlxGrid)

Forms : VueXML

  • Récupérez :

SubForms : JS - prototype.js et JS - scriptaculous.js

Vous adapterez tous les agents à votre application

agents_ajax

Bibliothèque de Script : LibOutilsWeb

Copiez toutes les ressources (Images, Files, Css)

2/ Explication fonctionnelle de l'exemple

Copiez/collez le lien ci-dessous dans ie, firefox ou chrome en modifiant le serveur et le chemin par les vôtres.

http://serveur/chemin/Ex_DxHtmlGrid.nsf/VueXML?OpenForm&TYPE=REG

vuexml_ajax

Dans la barre du haut, vous avez accès à plusieurs fonctions (RAZ des Filtres, Export Excel et Txt, nouveau document, suppression). A vous de voir ce dont vous avez besoin. Ce n'est pas lié à la Grid, il s'agit juste de petits outils dont je vous fais cadeau.

  • La 1ère colonne est masquée par une taille 0 (voir fonction JS DoOnload), il s'agit en fait de l'id des documents Notes.

voir également l'agent : myXML = myXML & {<cell>} & CStr(docSI.UniversalID) & {</cell>}

Nous faisons référence à cette colonne pour ouvrir, modifier, supprimer un document.

  • La 2ème colonne permet de sélectionner 1 ou  n document(s) pour la suppression et l'export (code à adapter si besoin)
  • La 3ème colonne un filtre type Combobox
  • La 4ème et la 5ème colonnes filtrent à la saisie.

3/ Explication technique de l'exemple

Tout d'abord il faut créer l'agent qui permet de générer le flux XML

Option Public
Option Declare
Use "LibOutilsWeb"
Sub Initialize
On Error Goto GestionErreur

' Initialisation
Dim erreur As String
Dim session As New NotesSession
Dim dbCourante As NotesDatabase
Set dbCourante = session.CurrentDatabase
Dim docCtx As NotesDocument
Set docCtx = session.DocumentContext

' Paramètres
Dim sQS As String, sKey As String
sQS = docCtx.Query_String_Decoded(0)
sKey = Ucase (unescapeText (getParameter ("TYPE", "&", sQS)))

' Affichage en tête XML
Dim myXML As String
Print {Content-Type:text/xml}
Print {<?xml version="1.0" encoding="ISO-8859-15"?>}
Print {<rows>}

' Affichage
'Dim nb As Integer
'nb = 0
Dim vueSI As NotesView
Dim nav As NotesViewNavigator
Set vueSI = dbCourante.Getview("vRegion")
Set nav = vueSI.CreateViewNav
Dim entry As NotesViewEntry
Set entry = nav.GetFirst
While Not entry Is Nothing
Dim docSI As NotesDocument
Set docSI = entry.Document
' myXML = {<row id="} & Cstr(nb) & {">}
myXML = {<row>}
myXML = myXML & {<cell>0</cell>}
myXML = myXML & {<cell>} & CStr(docSI.UniversalID) & {</cell>}
If sKey = "REG" Then
myXML = myXML & {<cell>} & encodeXML (docSI.GetItemValue ("Region")(0)) & {</cell>}
'URL (Commentaire)
'myXML = myXML & {<cell>} & encodeXML (docSI.GetItemValue ("Departement")(0)) & {^} & docCtx.URLBase(0) & {0/} & CStr(docSI.UniversalID) & {?OpenDocument^_blank</cell>}
'JAVASCRIPT
myXML = myXML & {<cell>} & encodeXML (docSI.GetItemValue ("Departement")(0)) & {^javascript:showPopWin("} & docCtx.URLBase(0) & {0/} & CStr(docSI.UniversalID) & {?OpenDocument", 850, 300, null,true);^</cell>}
myXML = myXML & {<cell>} & encodeXML (docSI.GetItemValue ("Numero")(0)) & {</cell>}
Else
myXML = myXML & {<cell>} & encodeXML (docSI.GetItemValue ("Departement")(0)) & {^javascript:showPopWin("} & docCtx.URLBase(0) & {0/} & CStr(docSI.UniversalID) & {?OpenDocument", 850, 300, null,true);^</cell>}
myXML = myXML & {<cell>} & encodeXML (docSI.GetItemValue ("Numero")(0)) & {</cell>}
End If
myXML = myXML & {</row>}
Print myXML
' nb = nb + 1
Set entry = nav.GetNext (entry)
Wend
Print {</rows>}

Exit Sub

GestionErreur:
erreur = "ERREUR ((WEB - VueXML)) / Initialize : " & Error & " (" & Err() & ") ligne " & Erl & "<br />" & erreur
Print erreur
Exit Sub

End Sub

 La seule difficulté est la création du lien doc :

myXML = myXML & {<cell>} & encodeXML (docSI.GetItemValue ("Departement")(0)) & {^javascript:showPopWin("} & docCtx.URLBase(0) & {0/} & CStr(docSI.UniversalID) & {?OpenDocument", 850, 300, null,true);^</cell>}

Pour créer un lien, il faut juste le délimiter avec les caractères ^code js ou lien^

La fonction showPopWin est un composant du fichier Modal_Common.js et Modal_Sub.js, elle ne fait pas parti de l'htmlxgrid. Il s'agit juste de montrer que l'on peut encapsuler d'autres modules JS sans problème du moment qu'ils soient compatibles entre eux.

Elle nous permet à l'ouverture / la création d'un document d'avoir un popup "moderne" !

La page est chargée au lancement de la fonction doOnLoad() et exécutée sur l’événement Onload

Le code de l'appel se trouve dans le JS Header

function doOnLoad() {

On instancie le constructeur dhtmlXGridObject

mygrid = new dhtmlXGridObject("gridbox");

On donne le chemin où sont stockées les images
mygrid.setImagePath("./dhtmlx/");

if (TypeAff == "REG") {

On donne le libellé des colonnes

mygrid.setHeader("Sel.,ID,Région,Département,Numero");

On définit le type de filtre (#master_checkbox : Select all, #text_filter : filtre de saisie, #select_filter_strict : combobox)

mygrid.attachHeader("#master_checkbox,#text_filter,#select_filter_strict,#text_filter,#text_filter");

On définit la taille des colonnes

mygrid.setInitWidths("30,0,220,370,*");

On donne leur position (tout à gauche : left)

mygrid.setColAlign("left,left,left,left,left");

On donne le type (ch : checkbox, ro : texte normal, link: lien, ed: Editable)
mygrid.setColTypes("ch,ro,ro,link,ed");

On donne le type de tri en cliquant sur la colonne (both)
mygrid.setColSorting("str,str,str,str,str");

}

else

{
mygrid.setHeader("Sel.,ID,Département,Numero");
mygrid.attachHeader("#master_checkbox,#text_filter,#text_filter,#text_filter");
mygrid.setInitWidths("30,0,220,*");
mygrid.setColAlign("left,left,left,left");
mygrid.setColTypes("ch,ro,link,ed");
mygrid.setColSorting("str,str,str,str");

}

//Code exécuté quand on check une ligne
mygrid.attachEvent("onCheckbox", function(rId,cInd,state){
var iddoc = mygrid.cells(rId,1).getValue();
if (state) var tbliddoc = aLstIdDocs.push(iddoc )
else {var index = aLstIdDocs.indexOf(iddoc);aLstIdDocs.splice(index, 1);}
});

//Code exécuté quand on edite un numéro de départment
mygrid.attachEvent("onEditCell", function(stage,rId,cInd,nValue,oValue){
if (stage ==2){
MajDepartement(mygrid.cells(rId,1).getValue(),nValue);
mygrid.cells(rId,4),setValue(nValue);
}
return true;
});

mygrid.setSkin("light");
mygrid.init();
mygrid.enableSmartRendering (true);
mygrid.loadXML(sChemRel + "/VueXML?OpenAgent&TYPE=" + TypeAff, onLoadFunction);
mygrid.attachEvent("onFilterEnd", function(elements){
mygrid._rowsBuffer = null;
mygrid.refreshFilters();
});

}

function MajDepartement(iddocument,newvaleur){
var url = sChemRel + "/(AjaxCellEditable)?OpenAgent&&IDDoc=" + iddocument + "&&NEWVAL="+ newvaleur;
new Ajax.Request(url, {onSuccess: function(response) {if (response.responseText !="")alert(response.responseText)}});
}

function refreshTableFilters() {
var filter1 = mygrid.getFilterElement(0);
var filter2 = mygrid.getFilterElement(0);
var colNum;
colNum == 0;
if ((filter1.value != "") && (filter2.value == "")) {
colNum == 2;
} else if ((filter2.value != "") && (filter1.value == "")) {
colNum == 1;
}
if (colNum != 0) {
for (var i=0; i<mygrid.getRowsNum(); i++){

}
}
}

function onLoadFunction() {
$("loading").hide();
$("gridbox").show();
}

function initFilters() {
mygrid.getFilterElement(2).value='';
mygrid.getFilterElement(3).value='';
mygrid.getFilterElement(4).value='';
mygrid.filterByAll();

}

//Exporter les documents au format txt et csv
function exporter(extension) {
var filtre1 = mygrid.getFilterElement(2).value;
var filtre2 = mygrid.getFilterElement(3).value;
var filtre3 = mygrid.getFilterElement(4).value;
var url = sChemRel + "/(ExportRestitution)?OpenAgent&&EXT=" + extension + "&&TYPE=" + TypeAff + "&&LSTID=" + aLstIdDocs.toString() + "&&F1=" + filtre1 + "&&F2=" + filtre2 + "&&F3=" + filtre3;
location.href = url;
}

//Nouveau doc
function NewDoc(){
var URL = sURLBase + "/fExemple?Openform" ;
showPopWin(URL, 850, 300, null,true);
}

//Suppression doc
function DeleteDoc(){
if (aLstIdDocs.toString()=="")return;
if(confirm("Confirmation suppression"))
{
var url = sChemRel + "/(AjaxDelete)?OpenAgent&&LSTID=" + aLstIdDocs.toString() ;
new Ajax.Request(url, {onSuccess: function(response) {if (response.responseText !="")alert(response.responseText);window.parent.location.href = window.parent.location.href;}});
}
}

//Popup
function PopupAjax(){
var URL = sURLBase + "/PopupPersonnes?OpenForm&qChamp=DOC_Demande_Declarant";
showPopWin(URL, 850, 300, null,true);
}

 Le code est facile à comprendre pour une personne connaissant html et JavaScript, je ne m'attarderait donc pas là-dessus.

Pour la colonne éditable, les boutons d'action, etc..., tout se trouve dans le JS Header.

Tous les JS et Styles sont déclarés dans le HTML Head Content.

Seuls le prototype et scriptaculous sont en subform pour éviter le problème des chemins relatifs. Ainsi le code est directement dans la page (ce qui est plus rapide).

Conclusion

Nous avons encore pu démontrer dans cet article que grâce aux différents framework Ajax nous pouvions réaliser des applications Notes plus modernes et ergonomiques.

J'appuie sur le fait que maintenant avec les XPages toutes ces fonctionnalités existent avec quelques ajustements mais certains clients ne sont pas encore prêts à franchir le pas.

@ Bientôt

 

 

 

 

 

 

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.