SP.ListOperation.Selection
Gestion de la sélection des éléments d'une liste
18/02/2010
1217 lectures
1 commentaire
5/5 (2 votes)
Dans les deux cours précédents, nous avons vu comment utiliser des fonctions assez basiques de l'Ecma Script. Dans ce cours, nous allons creuser un peu plus profond dans le code JavaScript de SharePoint pour apprendre à gérer la sélection des éléments dans une liste. Bien que cela puisse paraître trivial au premier coup d'œil, vous vous rendrez vite compte que c'est plus compliqué que ça en a l'air.
Pour illustrer nos propos, nous allons modifier quelque peu le Ribbon SharePoint pour obtenir ceci :
Les 6 boutons ajoutés permettront de réaliser certaines opérations de sélection des éléments de la liste. La première chose que nous allons faire est de créer le squelette des boutons dans le Ribbon pour ensuite ajouter le code JavaScript petit à petit. Ouvrez donc Visual Studio 2010 et créez un projet de type Empty SharePoint Project que vous nommerez AreaProg.Ecma.ListOperation :
L'image utilisée pour les boutons devant être déployée dans le dossier Images de SharePoint, nous déploierons cette solution au niveau de la ferme :
Enregistrez ensuite l'image suivante sur votre bureau en la renommant tools.png :
Retournez ensuite dans votre solution et cliquez avec le bouton droit de votre souris sur votre projet et choisissez Add > SharePoint "Images" Mapped Folder. Cette action aura pour effet d'ajouter un dossier Images dans votre projet. Le contenu de ce dossier sera automatiquement placé dans le dossier Images de SharePoint (14\TEMPLATE\IMAGES). Ajoutez ensuite l'image tools.png à l'intérieur du dossier contenu dans le dossier Images de votre solution.
Cliquez ensuite avec le bouton droit de votre souris sur votre projet et choisissez Add > New Item. Dans la fenêtre qui apparaît, sélectionnez Empty Element et nommez-le EcmaListOperation :
Cliquez ensuite sur l'élément Feature1 et modifiez sa propriété Folder Name sur EcmaListOperation. Enfin, ouvrez le fichier Elements.xml et tapez le code suivant :
Ce code sert à ajouter les 6 boutons dans le Ribbon. Si vous ne comprenez pas ce dernier, nous vous conseillons de lire les cours sur le Ribbon dans ce site. Notez que nous ajoutons ces boutons dans l'onglet List d'une liste générique. Notez également que nous ne nous préoccupons pas du Scaling de ces boutons. Effectivement, ici, le but est simplement de leur donner une fonction influant sur la sélection des éléments de la liste. Plongeons nous maintenant dans l'étude du code JavaScript nécessaire à la sélection des éléments.
Ce qui concerne la sélection des éléments se trouve dans le fichier 14\TEMPLATE\LAYOUTS\SP.Core.debug.js. Effectivement, si vous l'ouvrez et que vous vous rendez à la fin de ce fichier, vous pourrez voir le code suivant :
Ce code expose 4 fonctions permettant respectivement de sélectionner un élément, de récupérer les éléments sélectionnés, de récupérer la liste sélectionnée et de dé-sélectionner tous les éléments. Nous allons étudier ces fonctions une à une. Nous allons commencer par la fonction getSelectedItems. Modifiez donc le CommandUIHandler getSelectedItemsCommand de cette manière :
La première chose que nous faisons ici est simplement de récupérer le résultat de la fonction getSelectItems dans la variable items. Cette valeur est en fait une référence à tous les éléments sélectionnés dans la liste. Nous initialisons donc d'abord la variable r avec le nombre d'éléments sélectionnés. Ensuite, nous bouclons sur tous les éléments et nous plaçons leur ID dans la variable r. Enfin, nous affichons le contenu de cette variable. Ici, il n'y a rien de bien compliqué, nous nous contentons de parcourir la liste des éléments sélectionnés et d'en afficher l'ID :
Passons ensuite au CommandUIHandler getSelectedListCommand. Ce dernier va simplement afficher le résultat renvoyé par la fonction getSelectedList :
Ce code renvoi le résultat suivant :
Jusqu'à présent, tout se déroule parfaitement. Ce bouton affiche simplement le GUID de la liste et fonctionne donc très bien. Nous allons maintenant passer à la sélection des éléments, vous allez voir que c'est tout de suite moins évident. Je parlerai de temps en temps en "je" pour bien expliquer la méthode que j'ai utilisé pour comprendre comment me servir des fonctions. La première chose que nous allons faire est de tenter de nous servir de la fonction selectListItem de l'objet SP.ListOperation.Selection pour sélectionner un élément de la liste.
Si nous regardons le contenu de cette fonction, nous avons ceci :
Cette fonction attend donc deux paramètres : iid et bSelect. Malgré ce que vous pouvez penser, iid n'est pas simplement l'ID de l'élément à sélectionner. Effectivement, si vous essayer d'appeler cette fonction en passant 3 par exemple (pour l'élément avec l'ID 3), vous récolterez un erreur JavaScript. Comme vous pouvez le voir dans le code ci-dessus, la fonction selectListItem appelle la fonction SelectListItemNative. Après avoir ouvert quelques fichiers js de SharePoint, j'ai finalement découvert que le code de cette fonction se trouvait dans le fichier 14\TEMPLATE\LAYOUTS\1036\CORE.debug.js. J'imagine que dans la version anglais de SharePoint, celui-ci se trouve dans le dossier 14\TEMPLATE\LAYOUTS\1033. Si nous ouvrons ce fichier et que nous faisons une recherche sur la fonction SelectListItemNative, nous obtenons ceci :
En analysant ce code en diagonale, il est facile de découvrir l'utilité de bSelect. Effectivement, vous pouvez voir que cette valeur est testée et que si elle est sur true, la valeur de ctxT.CurrentSelectedItems est incrémentée. Dans le cas contraire, cette valeur est décrémentée. Cet argument permet donc de sélectionner (true) ou de dé-sélectionner (false) un élément. Par contre, l'attribut iid reste toujours aussi mystérieux. Effectivement, le seul endroit dans cette fonction où il est utilisé est dans la fonction GetCtxRgiidFromIid. Si nous faisons une recherche sur cette fonction, nous tombons sur :
Après une analyse de ce code, nous pouvons être en mesure de comprendre le format de cet iid. Effectivement, cette fonction commence par faire un split de cet iid avec la virgule comme séparateur. Elle vérifie ensuite que le tableau résultant contient bien 3 éléments et que le second n'est pas vide. Ensuite, elle place le premier élément de ce tableau dans la variable ctxNum et il récupère le contexte actuel avec cette valeur. Tout cela pour dire que le format de cet iid ressemble à quelque chose du genre X,Y,Z.
Il apparaît donc que la façon de sélectionner un élément de la liste est de faire passer l'iid de cet élément. Mais comment récupérer ce dernier ? Pour cela, nous allons utiliser Firefox et FireBug (pas obligatoire, mais plus simple). Effectivement, si nous ouvrons notre liste avec Firefox, que nous activons Firebug et que nous inspectons les éléments de la liste, nous tombons sur ceci :
Nous voyons donc que chaque élément de la liste correspond à un élément tr du code HTML de la page. Ce que nous voyons également, c'est que chacune de ces lignes contient un attribut iid : 1,6,0, 1,7,0... Voici donc le fameux iid des éléments. Celui-ci est composé de l'ID du contexte et de l'ID de l'élément. J'ignore à quoi sert le 0 final (principalement parce que c'est toujours 0). Nous allons donc tester la fonction selectListItem. Etant donné que l'ID du contexte change, nous allons tester la fonction en tapant le code javascript dans la barre d'adresse d'Internet Explorer, car nous ne faisons que des tests. Tapez donc :
Ici, bien évidemment, vous devrez remplacer 2,6,0 par un iid présent dans le code source de votre page. Ne vous posez pas trop de questions pour l'instant. Actuellement, nous ne faisons que des tests, tout s'éclairera vers la fin. Nous englobons le code dans une fonction (nommée foo) car sinon la page se serait effacée et aurait affiché le résultat renvoyé par la fonction. Englober celle-ci dans une fonction permet d'éviter ce comportement.
De toute manière, vous êtes certainement en train de vous lamenter en disant que cela ne fonctionne pas (c'est du vécu :-p). En fait, cela fonctionne, mais pas entièrement. Effectivement, si vous cliquez que le bouton Get Selected Items, vous verrez ceci :
Malgré que vous ne voyez aucun élément sélectionné dans la liste, le bouton vous indique que l'élément 6 est sélectionné. Et effectivement, si vous vous rendez dans l'onglet Elements de la liste, vous verrez que certaines options sont disponibles :
En fait, ceci est normal. Effectivement, la fonction a bien fonctionné et un élément à bien été sélectionné, cependant, ces changements ne sont pas répercutés sur l'UI. Ceci peut ne pas être embêtant si l'utilisateur n'a pas besoin de voir les éléments sélectionnés, mais dans le cas contraire, c'est un grand problème.
Nous allons donc creuser encore un petit peu pour voir comment remédier à ce problème. Si nous revenons sur Firefox avec Firebug toujours activé, nous pouvons remarquer quelque chose. Effectivement, si vous observez une ligne (tr) du tableau et que vous comparez sa structure quand elle est sélectionnée ou non, vous verrez une légère différence. Effectivement, une ligne non sélectionnée sera la suivante :
Alors quand quand elle est sélectionnée, sa structure sera la suivante :
Vous remarquerez aisément que la ligne contient la classe s4-itm-selected en plus. J'ai donc un peu petit peu examiné le code HTML de la page pour essayer de voir quelle fonction était appelée lors du click sur la ligne, mais je n'ai malheureusement pas réussi à la localiser de cette manière. J'ai donc fait une recherche sur s4-itm-selected dans le fichier CORE.debug.js et j'ai trouvé ceci :
Ce code est relativement similaire à la fonction SelectListItemNative à quelques différences près. La plus grande étant bien évidemment les lignes qui permettent d'ajouter ou de supprimer la classe s4-itm-selected à la ligne représentant l'élément. La fonction utilise également la fonction GetItemRowCbx pour récupérer le checkbox de la ligne et le sélectionner au besoin.
Une autre différence se situe également dans la liste des paramètres. Cette fois, cette fonction en attend plus que la fonction selectListItemNative. Le premier devra contenir le contexte actuel, le second sera l'iid de l'élément à sélectionner. Le troisième sera le rgiid. Nous avons vu précédemment dans la fonction GetCtxRgiidFromIid que le rgiid n'était que le tableau "splité" de l'iid. Le quatrième paramètre correspond à la référence de la ligne représentant l'élément et ensuite, le dernier paramètre indique si nous sélectionnons ou dé-sélectionnons l'élément. 4 paramètres sont assez faciles à récupérer, mais comment récupérer tr ?
Le but ici, va donc être de récupérer une référence au tableau contenant les éléments. Ici, je dois l'avouer, j'ai eu un peu de chance, car en cherchant un peu dans le code, j'ai trouvé que le tableau pouvait être récupéré grâce à GetCurrentCtx().clvp.tab. La fonction GetCurrentCtx récupère simplement le contexte d'exécution actuel.
Modifiez donc maintenant le CommandUIHandler SelectAllCommand de cette manière :
Nous allons donc expliquer ce code ligne par ligne. Ce bouton va permettre de sélectionner tous les éléments de la liste. Ici, nous pourrions utiliser JQuery, mais je préfère montrer les exemples en JavaScript pur pour que vous vous rendiez bien compte de ce qui se passe réellement. Après, libre à vous d'utiliser JQuery, du moment que vous comprenez ce qui se passe réellement, c'est l'important.
Nous commençons donc par récupérer une référence aux lignes du tableau. Comme nous l'avons vu tout à l'heure, GetCurrentCtx permet de récupérer le contexte d'exécution actuel. Sa propriété clvp.tab permet de récupérer une référence au tableau contenant les éléments et enfin, rows permet de récupérer une référence à toutes les lignes du tableau
Nous parcourons ensuite toutes les lignes de ce tableau grâce à la boucle for. Nous mettons < et non < car nous sommes dans une balise XML. Pour chacune des lignes, nous utilisons la fonction getAttribute pour voir si cette ligne contient bien un iid. Si c'est le cas, nous appelons la fonction GetCtxRgiidFromIid pour récupérer les informations nécessaires à l'appel de la fonction SelectListItem. Si vous comparez la fonction SelectListItem et SelectListItemNative, vous remarquerez que la deuxième attend juste un iid en paramètre et récupère le contexte et le rgiid grâce à la fonction GetCtxRgiidFromIid. La fonction SelectListItem, quant à elle, ne fait pas ça, elle attend directement le contexte, l'iid et le rgiid en paramètre, nous appelons donc nous même la fonction GetCtxRgiidFromIid pour récupérer ces informations.
Ensuite, nous appelons simplement la fonction SelectListItem. Nous récupérons le premier et le troisième paramètre dans l'objet renvoyé par la fonction GetCtxRgiidFromIid. Nous récupérons l'iid (deuxième paramètre) grâce à la fonction getAttribute appliquée sur la ligne. Le quatrième argument est la ligne elle-même alors que le dernier argument est positionné sur true pour indiquer que nous voulons sélectionner l'élément. Si vous compilez, déployez et testez votre bouton, vous sauterez de joie en vous rendant compte que ca fonctionne. Mais comme j'aime être rabat-joie, je vous indiquerai que cela ne fonctionne pas encore entièrement. Effectivement, si vous cliquez sur l'onglet Elements du Ribbon, vous verrez ceci :
Le problème est que bien que les éléments sont sélectionnés, l'option "Supprimer" (par exemple), n'est pas disponible. Si vous vous souvenez, nous n'avions pas ce problème lorsque nous utilisions la fonction SelectListItemNative. Si nous comparons de nouveau les deux fonctions, vous apercevrez certainement une autre différence. La présence de cette ligne dans la fonction SelectListItemNative :
C'est en fait cette fonction qui va permettre de réagir au fait qu'un élément à été sélectionné. Modifiez donc le code de votre CommandUIHandler de cette manière :
Compilez, déployez et testez maintenant la solution :
Cette fois, le bouton de suppression est bien disponible. Vous voyez, ce n'était pas très compliqué, il suffisait de creuser un petit peu. Modifiez maitnenant votre CommandUIHandler SelectOneCommand de cette manière :
Ici, le code est sensiblement le même. Nous commençons simplement par afficher un prompt pour demander à l'utilisateur l'ID de l'élément à sélectionner. Si le prompt ne s'affiche pas, il est possible qu'Internet Explorer le bloque, modifiez alors vos préférences pour autoriser l'ouverture du prompt. Nous ajoutons également une condition dans la boucle for pour vérifier que l'ID de l'élément actuel est bien égal à l'ID de l'élément à supprimer. Comme nous l'avons dit précédemment, un iid est composé de l'ID du contexte et de l'ID de l'élément qu'il identifie. Donc, rgiid[1] contient bien l'ID de l'élément.
Modifiez maintenant le CommandUIHandler DeselectOneCommand de cette manière :
Ici, le code est exactement que le précédent à la différence près que nous faisons passer la valeur false comme cinquième attribut de la fonction de sélection de l'élément, ce qui a pour effet de dé-sélectionner l'élément.
Nous n'allons pas entrer dans les détails comme précédemment, mais la fonction deselectAllListItems a le même comportement que la fonction selectListItem de l'objet SP.ListOperation.Selection. Effectivement, les éléments vont bien être dé-sélectionnés, mais rien ne sera répercuté au niveau de l'UI, nous allons donc devoir utiliser la méthode DeselectAllItems. Modifiez donc le dernier CommandUIHandler de cette manière :
Cette fonction attend 3 paramètres. Le premier est bien évidemment le contexte d'exécution actuel. Le deuxième doit contenir une référence aux lignes du tableau contenant les éléments (que nous récupérons de la même manière que précédemment). Enfin, le dernier paramètre indique s'il faut mettre à jour ou non l'affichage. Nous vous conseillons donc de le mettre sur true pour désactiver les options qui ont été activées lors de la sélection d'un élément.
Vous pouvez maintenant compiler, déployer et tester votre projet pour voir que tout fonctionne à merveille. Avant de terminer le cours, j'aimerai juste ajouter un petit quelque chose. Sachez que dans la page, le contexte d'exécution est très intéressant et contient beaucoup d'informations. Pour les voir, c'est assez simple. Si vous regardez le code de la page contenant une liste SharePoint, vous apercevrez ceci :
Vous pouvez donc voir que le contexte contient un bon nombre de propriétés intéressantes exploitables en JavaScript.
Télécharger les sources de l'exemple
Pour illustrer nos propos, nous allons modifier quelque peu le Ribbon SharePoint pour obtenir ceci :
Les 6 boutons ajoutés permettront de réaliser certaines opérations de sélection des éléments de la liste. La première chose que nous allons faire est de créer le squelette des boutons dans le Ribbon pour ensuite ajouter le code JavaScript petit à petit. Ouvrez donc Visual Studio 2010 et créez un projet de type Empty SharePoint Project que vous nommerez AreaProg.Ecma.ListOperation :
L'image utilisée pour les boutons devant être déployée dans le dossier Images de SharePoint, nous déploierons cette solution au niveau de la ferme :
Enregistrez ensuite l'image suivante sur votre bureau en la renommant tools.png :
Retournez ensuite dans votre solution et cliquez avec le bouton droit de votre souris sur votre projet et choisissez Add > SharePoint "Images" Mapped Folder. Cette action aura pour effet d'ajouter un dossier Images dans votre projet. Le contenu de ce dossier sera automatiquement placé dans le dossier Images de SharePoint (14\TEMPLATE\IMAGES). Ajoutez ensuite l'image tools.png à l'intérieur du dossier contenu dans le dossier Images de votre solution.
Cliquez ensuite avec le bouton droit de votre souris sur votre projet et choisissez Add > New Item. Dans la fenêtre qui apparaît, sélectionnez Empty Element et nommez-le EcmaListOperation :
Cliquez ensuite sur l'élément Feature1 et modifiez sa propriété Folder Name sur EcmaListOperation. Enfin, ouvrez le fichier Elements.xml et tapez le code suivant :
Ce code sert à ajouter les 6 boutons dans le Ribbon. Si vous ne comprenez pas ce dernier, nous vous conseillons de lire les cours sur le Ribbon dans ce site. Notez que nous ajoutons ces boutons dans l'onglet List d'une liste générique. Notez également que nous ne nous préoccupons pas du Scaling de ces boutons. Effectivement, ici, le but est simplement de leur donner une fonction influant sur la sélection des éléments de la liste. Plongeons nous maintenant dans l'étude du code JavaScript nécessaire à la sélection des éléments.
Ce qui concerne la sélection des éléments se trouve dans le fichier 14\TEMPLATE\LAYOUTS\SP.Core.debug.js. Effectivement, si vous l'ouvrez et que vous vous rendez à la fin de ce fichier, vous pourrez voir le code suivant :
Ce code expose 4 fonctions permettant respectivement de sélectionner un élément, de récupérer les éléments sélectionnés, de récupérer la liste sélectionnée et de dé-sélectionner tous les éléments. Nous allons étudier ces fonctions une à une. Nous allons commencer par la fonction getSelectedItems. Modifiez donc le CommandUIHandler getSelectedItemsCommand de cette manière :
La première chose que nous faisons ici est simplement de récupérer le résultat de la fonction getSelectItems dans la variable items. Cette valeur est en fait une référence à tous les éléments sélectionnés dans la liste. Nous initialisons donc d'abord la variable r avec le nombre d'éléments sélectionnés. Ensuite, nous bouclons sur tous les éléments et nous plaçons leur ID dans la variable r. Enfin, nous affichons le contenu de cette variable. Ici, il n'y a rien de bien compliqué, nous nous contentons de parcourir la liste des éléments sélectionnés et d'en afficher l'ID :
Passons ensuite au CommandUIHandler getSelectedListCommand. Ce dernier va simplement afficher le résultat renvoyé par la fonction getSelectedList :
Ce code renvoi le résultat suivant :
Jusqu'à présent, tout se déroule parfaitement. Ce bouton affiche simplement le GUID de la liste et fonctionne donc très bien. Nous allons maintenant passer à la sélection des éléments, vous allez voir que c'est tout de suite moins évident. Je parlerai de temps en temps en "je" pour bien expliquer la méthode que j'ai utilisé pour comprendre comment me servir des fonctions. La première chose que nous allons faire est de tenter de nous servir de la fonction selectListItem de l'objet SP.ListOperation.Selection pour sélectionner un élément de la liste.
Si nous regardons le contenu de cette fonction, nous avons ceci :
Cette fonction attend donc deux paramètres : iid et bSelect. Malgré ce que vous pouvez penser, iid n'est pas simplement l'ID de l'élément à sélectionner. Effectivement, si vous essayer d'appeler cette fonction en passant 3 par exemple (pour l'élément avec l'ID 3), vous récolterez un erreur JavaScript. Comme vous pouvez le voir dans le code ci-dessus, la fonction selectListItem appelle la fonction SelectListItemNative. Après avoir ouvert quelques fichiers js de SharePoint, j'ai finalement découvert que le code de cette fonction se trouvait dans le fichier 14\TEMPLATE\LAYOUTS\1036\CORE.debug.js. J'imagine que dans la version anglais de SharePoint, celui-ci se trouve dans le dossier 14\TEMPLATE\LAYOUTS\1033. Si nous ouvrons ce fichier et que nous faisons une recherche sur la fonction SelectListItemNative, nous obtenons ceci :
En analysant ce code en diagonale, il est facile de découvrir l'utilité de bSelect. Effectivement, vous pouvez voir que cette valeur est testée et que si elle est sur true, la valeur de ctxT.CurrentSelectedItems est incrémentée. Dans le cas contraire, cette valeur est décrémentée. Cet argument permet donc de sélectionner (true) ou de dé-sélectionner (false) un élément. Par contre, l'attribut iid reste toujours aussi mystérieux. Effectivement, le seul endroit dans cette fonction où il est utilisé est dans la fonction GetCtxRgiidFromIid. Si nous faisons une recherche sur cette fonction, nous tombons sur :
Après une analyse de ce code, nous pouvons être en mesure de comprendre le format de cet iid. Effectivement, cette fonction commence par faire un split de cet iid avec la virgule comme séparateur. Elle vérifie ensuite que le tableau résultant contient bien 3 éléments et que le second n'est pas vide. Ensuite, elle place le premier élément de ce tableau dans la variable ctxNum et il récupère le contexte actuel avec cette valeur. Tout cela pour dire que le format de cet iid ressemble à quelque chose du genre X,Y,Z.
Il apparaît donc que la façon de sélectionner un élément de la liste est de faire passer l'iid de cet élément. Mais comment récupérer ce dernier ? Pour cela, nous allons utiliser Firefox et FireBug (pas obligatoire, mais plus simple). Effectivement, si nous ouvrons notre liste avec Firefox, que nous activons Firebug et que nous inspectons les éléments de la liste, nous tombons sur ceci :
Nous voyons donc que chaque élément de la liste correspond à un élément tr du code HTML de la page. Ce que nous voyons également, c'est que chacune de ces lignes contient un attribut iid : 1,6,0, 1,7,0... Voici donc le fameux iid des éléments. Celui-ci est composé de l'ID du contexte et de l'ID de l'élément. J'ignore à quoi sert le 0 final (principalement parce que c'est toujours 0). Nous allons donc tester la fonction selectListItem. Etant donné que l'ID du contexte change, nous allons tester la fonction en tapant le code javascript dans la barre d'adresse d'Internet Explorer, car nous ne faisons que des tests. Tapez donc :
Ici, bien évidemment, vous devrez remplacer 2,6,0 par un iid présent dans le code source de votre page. Ne vous posez pas trop de questions pour l'instant. Actuellement, nous ne faisons que des tests, tout s'éclairera vers la fin. Nous englobons le code dans une fonction (nommée foo) car sinon la page se serait effacée et aurait affiché le résultat renvoyé par la fonction. Englober celle-ci dans une fonction permet d'éviter ce comportement.
De toute manière, vous êtes certainement en train de vous lamenter en disant que cela ne fonctionne pas (c'est du vécu :-p). En fait, cela fonctionne, mais pas entièrement. Effectivement, si vous cliquez que le bouton Get Selected Items, vous verrez ceci :
Malgré que vous ne voyez aucun élément sélectionné dans la liste, le bouton vous indique que l'élément 6 est sélectionné. Et effectivement, si vous vous rendez dans l'onglet Elements de la liste, vous verrez que certaines options sont disponibles :
En fait, ceci est normal. Effectivement, la fonction a bien fonctionné et un élément à bien été sélectionné, cependant, ces changements ne sont pas répercutés sur l'UI. Ceci peut ne pas être embêtant si l'utilisateur n'a pas besoin de voir les éléments sélectionnés, mais dans le cas contraire, c'est un grand problème.
Nous allons donc creuser encore un petit peu pour voir comment remédier à ce problème. Si nous revenons sur Firefox avec Firebug toujours activé, nous pouvons remarquer quelque chose. Effectivement, si vous observez une ligne (tr) du tableau et que vous comparez sa structure quand elle est sélectionnée ou non, vous verrez une légère différence. Effectivement, une ligne non sélectionnée sera la suivante :
Alors quand quand elle est sélectionnée, sa structure sera la suivante :
Vous remarquerez aisément que la ligne contient la classe s4-itm-selected en plus. J'ai donc un peu petit peu examiné le code HTML de la page pour essayer de voir quelle fonction était appelée lors du click sur la ligne, mais je n'ai malheureusement pas réussi à la localiser de cette manière. J'ai donc fait une recherche sur s4-itm-selected dans le fichier CORE.debug.js et j'ai trouvé ceci :
Ce code est relativement similaire à la fonction SelectListItemNative à quelques différences près. La plus grande étant bien évidemment les lignes qui permettent d'ajouter ou de supprimer la classe s4-itm-selected à la ligne représentant l'élément. La fonction utilise également la fonction GetItemRowCbx pour récupérer le checkbox de la ligne et le sélectionner au besoin.
Une autre différence se situe également dans la liste des paramètres. Cette fois, cette fonction en attend plus que la fonction selectListItemNative. Le premier devra contenir le contexte actuel, le second sera l'iid de l'élément à sélectionner. Le troisième sera le rgiid. Nous avons vu précédemment dans la fonction GetCtxRgiidFromIid que le rgiid n'était que le tableau "splité" de l'iid. Le quatrième paramètre correspond à la référence de la ligne représentant l'élément et ensuite, le dernier paramètre indique si nous sélectionnons ou dé-sélectionnons l'élément. 4 paramètres sont assez faciles à récupérer, mais comment récupérer tr ?
Le but ici, va donc être de récupérer une référence au tableau contenant les éléments. Ici, je dois l'avouer, j'ai eu un peu de chance, car en cherchant un peu dans le code, j'ai trouvé que le tableau pouvait être récupéré grâce à GetCurrentCtx().clvp.tab. La fonction GetCurrentCtx récupère simplement le contexte d'exécution actuel.
Modifiez donc maintenant le CommandUIHandler SelectAllCommand de cette manière :
Nous allons donc expliquer ce code ligne par ligne. Ce bouton va permettre de sélectionner tous les éléments de la liste. Ici, nous pourrions utiliser JQuery, mais je préfère montrer les exemples en JavaScript pur pour que vous vous rendiez bien compte de ce qui se passe réellement. Après, libre à vous d'utiliser JQuery, du moment que vous comprenez ce qui se passe réellement, c'est l'important.
Nous commençons donc par récupérer une référence aux lignes du tableau. Comme nous l'avons vu tout à l'heure, GetCurrentCtx permet de récupérer le contexte d'exécution actuel. Sa propriété clvp.tab permet de récupérer une référence au tableau contenant les éléments et enfin, rows permet de récupérer une référence à toutes les lignes du tableau
Nous parcourons ensuite toutes les lignes de ce tableau grâce à la boucle for. Nous mettons < et non < car nous sommes dans une balise XML. Pour chacune des lignes, nous utilisons la fonction getAttribute pour voir si cette ligne contient bien un iid. Si c'est le cas, nous appelons la fonction GetCtxRgiidFromIid pour récupérer les informations nécessaires à l'appel de la fonction SelectListItem. Si vous comparez la fonction SelectListItem et SelectListItemNative, vous remarquerez que la deuxième attend juste un iid en paramètre et récupère le contexte et le rgiid grâce à la fonction GetCtxRgiidFromIid. La fonction SelectListItem, quant à elle, ne fait pas ça, elle attend directement le contexte, l'iid et le rgiid en paramètre, nous appelons donc nous même la fonction GetCtxRgiidFromIid pour récupérer ces informations.
Ensuite, nous appelons simplement la fonction SelectListItem. Nous récupérons le premier et le troisième paramètre dans l'objet renvoyé par la fonction GetCtxRgiidFromIid. Nous récupérons l'iid (deuxième paramètre) grâce à la fonction getAttribute appliquée sur la ligne. Le quatrième argument est la ligne elle-même alors que le dernier argument est positionné sur true pour indiquer que nous voulons sélectionner l'élément. Si vous compilez, déployez et testez votre bouton, vous sauterez de joie en vous rendant compte que ca fonctionne. Mais comme j'aime être rabat-joie, je vous indiquerai que cela ne fonctionne pas encore entièrement. Effectivement, si vous cliquez sur l'onglet Elements du Ribbon, vous verrez ceci :
Le problème est que bien que les éléments sont sélectionnés, l'option "Supprimer" (par exemple), n'est pas disponible. Si vous vous souvenez, nous n'avions pas ce problème lorsque nous utilisions la fonction SelectListItemNative. Si nous comparons de nouveau les deux fonctions, vous apercevrez certainement une autre différence. La présence de cette ligne dans la fonction SelectListItemNative :
C'est en fait cette fonction qui va permettre de réagir au fait qu'un élément à été sélectionné. Modifiez donc le code de votre CommandUIHandler de cette manière :
Compilez, déployez et testez maintenant la solution :
Cette fois, le bouton de suppression est bien disponible. Vous voyez, ce n'était pas très compliqué, il suffisait de creuser un petit peu. Modifiez maitnenant votre CommandUIHandler SelectOneCommand de cette manière :
Ici, le code est sensiblement le même. Nous commençons simplement par afficher un prompt pour demander à l'utilisateur l'ID de l'élément à sélectionner. Si le prompt ne s'affiche pas, il est possible qu'Internet Explorer le bloque, modifiez alors vos préférences pour autoriser l'ouverture du prompt. Nous ajoutons également une condition dans la boucle for pour vérifier que l'ID de l'élément actuel est bien égal à l'ID de l'élément à supprimer. Comme nous l'avons dit précédemment, un iid est composé de l'ID du contexte et de l'ID de l'élément qu'il identifie. Donc, rgiid[1] contient bien l'ID de l'élément.
Modifiez maintenant le CommandUIHandler DeselectOneCommand de cette manière :
Ici, le code est exactement que le précédent à la différence près que nous faisons passer la valeur false comme cinquième attribut de la fonction de sélection de l'élément, ce qui a pour effet de dé-sélectionner l'élément.
Nous n'allons pas entrer dans les détails comme précédemment, mais la fonction deselectAllListItems a le même comportement que la fonction selectListItem de l'objet SP.ListOperation.Selection. Effectivement, les éléments vont bien être dé-sélectionnés, mais rien ne sera répercuté au niveau de l'UI, nous allons donc devoir utiliser la méthode DeselectAllItems. Modifiez donc le dernier CommandUIHandler de cette manière :
Cette fonction attend 3 paramètres. Le premier est bien évidemment le contexte d'exécution actuel. Le deuxième doit contenir une référence aux lignes du tableau contenant les éléments (que nous récupérons de la même manière que précédemment). Enfin, le dernier paramètre indique s'il faut mettre à jour ou non l'affichage. Nous vous conseillons donc de le mettre sur true pour désactiver les options qui ont été activées lors de la sélection d'un élément.
Vous pouvez maintenant compiler, déployer et tester votre projet pour voir que tout fonctionne à merveille. Avant de terminer le cours, j'aimerai juste ajouter un petit quelque chose. Sachez que dans la page, le contexte d'exécution est très intéressant et contient beaucoup d'informations. Pour les voir, c'est assez simple. Si vous regardez le code de la page contenant une liste SharePoint, vous apercevrez ceci :
Vous pouvez donc voir que le contexte contient un bon nombre de propriétés intéressantes exploitables en JavaScript.
Télécharger les sources de l'exemple













1 commentaires
Marc13100 a dit:
tres bon cours
Ajouter un commentaire