Skip to main content

Développement d'un page component simple pour intercepter les
commandes d'un bouton personnel du Ribbon

Sommaire

Introduction

Pour ajouter des éléments dans le « Ribbon », une technique utilisée consiste à développer des « custom actions ». Dans le code de celles-ci, nous insérons directement le code « JavaScript » nécessaire au traitement du bouton dans le fichier XML de déclaration.

Cette technique, bien que simple, a ses inconvénients. Le premier est que nous définissons tel quel le code JavaScript relatif au bouton dans le fichier XML. Cela ne pose pas de problème quand le code JavaScript est court, mais lorsqu’il nous faut exécuter plus d’instructions, cela devient vite gênant.

C’est pour cela que SharePoint a mis en place un système pour gérer les « événements » du Ribbon. Effectivement, un « dispatcher » est attaché au Ribbon et va être responsable de la redirection des commandes de celui-ci vers les bons codes JavaScript. Nous allons voir cela grâce à un exemple concret.

Avant de commencer, il faut savoir que développer un « Page component » n’est pas aussi simple que directement taper le code JavaScript dans le fichier XML. Effectivement, pour faire cela, nous allons d’une certaine manière devoir implémenter une « interface » JavaScript. Ainsi, le « Ribbon » saura que notre « Page Component » comporte différentes fonctions qu’il va pouvoir appeler à sa guise pour exécuter différentes opérations à différents moments.

Développement

Création du projet

Ouvrez Visual Studio 2010 et créez un nouveau projet de type « Empty SharePoint Project » que vous nommerez « MSDN.MyPC ».

01

Laissez la deuxième option cochée pour déployer la solution au niveau de la ferme. La première chose que nous allons devoir faire est bien évidemment écrire le code XML permettant d’ajouter un bouton dans le Ribbon. Ce bouton se placera dans le groupe « New » des listes génériques. Faites donc un clic droit sur votre projet et choisissez Add > New Item > « Empty Element ». Nommez cet élément « MSDN.MyPC » et validez.

02

Avant de continuer, cliquez une fois sur « Feature1 », pressez F2 et rentrez « MSDN.MyPC » pour renommer le dossier dans lequel sera déployée la feature.

Création de la custom action

Ouvrez maintenant votre fichier « Elements.xml » et tapez le code suivant :

<CustomAction Id="RedoAction"
            RegistrationId="100"
            RegistrationType="List"
            Location="CommandUI.Ribbon.ListView">
  <CommandUIExtension>
    <CommandUIDefinitions>
      <CommandUIDefinition Location="Ribbon.ListItem.New.Controls._children">

        <Button Id="RedoButton"
                Command="RedoButtonClick"
                LabelText="Redo"
                ToolTipTitle="Redo the last action"
                Image16by16="/_layouts/images/MSDN.MyPC/redo16x16.png"
                Image32by32="/_layouts/images/MSDN.MyPC/redo32x32.png"
                ToolTipDescription="Redo Description"
                TemplateAlias="o1"/>
      </CommandUIDefinition>

    </CommandUIDefinitions>
  </CommandUIExtension>
</CustomAction>

Pour l’instant, il n’y a rien de bien compliqué. Si vous ne comprenez pas ces quelques lignes de code, nous vous conseillons fortement de lire les cours de cette page :

http://www.areaprog.com/SP2010/section-86-sharepoint-2010-ribbon

Ce code va donc ajouter un nouveau bouton dans le groupe « New » des listes génériques. Celui-ci va utiliser deux images. Faites donc un clic droit sur votre projet de choisissez Add > New > SharePoint « Images » Mapped Folder. Toutes les images se trouvant dans ce dossier seront automatiquement uploadées dans le dossier système « Images » de Sharepoint. Visual Studio crée automatiquement un dossier du nom de votre projet pour bien séparer vos différents développements. Nous ajoutons ces images dans ce dossier :

03

Celles-ci doivent être nommées « redo16x16.png » et « redo32x32.png ».

A l’heure actuelle, votre « feature » se contente simplement d’ajouter un bouton dans le Ribbon. Si vous vouliez effectuer des actions lors du clic du bouton, il vous suffirait de lui attribuer une commande et de faire un « CommandUIHandler » interceptant celle-ci pour effectuer différentes opérations. C’est effectivement une solution, mais ici, nous allons voir comment le faire en passant par un « Page Component ».

Création du page component

Comme vous vous en doutez, un « Page Component » est une série d’instructions JavaScript qui vont permettre d’ajouter votre contrôle/groupe/onglet comme élément à part entière du Ribbon. Avant d’aller plus loin dans les explications, faites un clic droit sur votre projet et choisissez Add > New > SharePoint « Layouts » Mapped Folder. Faites ensuite un clic droit sur le dossier créé dans le dossier « Layouts » et faites Add > New Item. Dans la fenêtre qui s’ouvre, sélectionnez « JScript File » et nommez-le « MSDN.MyPC.js ».

04

Comme nous l’avons vu précédemment, le Ribbon dispose d’un « dispatcher ». En fait, celui-ci va se charger de rediriger les différentes commandes vers les différents fichiers JavaScript de SharePoint. Il faut voir ce « dispatcher » comme un routeur. Le Ribbon est un ensemble de contrôles pouvant lancer un ensemble de commande. Lorsque l’on va cliquer sur un bouton, le Ribbon va passer la commande au « dispatcher ». De manière simplifiée, celui-ci dispose d’une table des commandes indiquant quelles fonctions JavaScript sont attachées à ces commandes. Ainsi, lorsqu’il reçoit une commande, il exécute directement les fonctions JavaScript attachées à celle-ci.

Pour pouvoir faire cela, le « dispatcher » doit être capable de discuter avec votre « Page Component » comme il le fait avec ceux de SharePoint. Pour cela, nous allons devoir implémenter une « interface » JavaScript pour assurer au « dispatcher » que les commandes qu’il essaye d’exécuter sont bien présentes.

Avant toute chose, pour pouvoir enregistrer votre « Page Component » dans le Ribbon, vous allez devoir attendre que celui-ci soit entièrement chargé, tapez donc ceci dans votre fichier « JavaScript » :

ExecuteOrDelayUntilScriptLoaded(registerMyPC, 'SP.Ribbon.js');

function registerMyPC() {

}

Ici, nous allons simplement attendre que le fichier JavaScript relatif au Ribbon (SP.Ribbon.js) soit entièrement chargé. Une fois celui-ci chargé, nous passons le relai à la fonction « registerMyPC » qui va se charger d’enregistrer votre « Page Component » dans le Ribbon. Bien entendu, le code va être légèrement plus compliqué que dans notre ancienne méthode mais sa logique le rend très accessible.

La première chose que nous allons devoir faire est « créer » notre « namespace » JavaScript. Pour cela, nous utilisons la classe SharePoint « Type » :

Type.registerNamespace("MSDN.MyPC");

Nous utilisons simplement la fonction « registerNamespace » en lui faisant passer le nom de notre « namespace ». Nous allons ensuite créer un objet représentant notre « Page Component » :

MSDN.MyPC.PageComponent = function () {
    MSDN.MyPC.PageComponent.initializeBase(this);
};

Comme vous le voyez, nous utilisons bien le « namespace MSDN.MyPC » enregistré un peu plus haut. Ici, quand nous allons créer un objet du type « MSDN.MyPC.PageComponent », cette fonction (une sorte de constructeur) va simplement appeler la fonction « initializeBase » de la classe parent (« Type ») en lui faisant passer l’objet courant.

Nous allons maintenant créer le prototype de notre classe. Le prototype va donc permettre de définir toutes les méthodes et propriétés attachées à notre objet.

MSDN.MyPC.PageComponent.prototype = {


}

Nous rajoutons simplement « .prototype » au nom de notre objet. Nous allons devoir indiquer au « Ribbon » le nom des différentes commandes que notre « PageComponent » va être en mesure de traiter. Ici, nous allons faire simple, le bouton affichera simplement une boite de dialogue lorsque l'on cliquera dessus. Cependant, même si notre « Page Component » ne doit gérer qu’une seule commande, nous devons renvoyer celle-ci dans un tableau. Nous déclarons donc celui-ci :

commands: null,

Nous allons ensuite devoir implémenter une fonction « init » qui sera appelée par le « Ribbon » lors de l’initialisation de notre « Page Component ».

init: function () { },

Même si celle-ci est vide, nous la déclarons pour que SharePoint ne soit pas bloqué lorsqu’il va essayer de l’exécuter via le « Ribbon ».

Comme nous l’avons vu tout à l’heure, nous allons devoir indiquer au « Ribbon » le nom des différentes commandes que notre « Page Component » va pouvoir traiter. Nous allons donc implémenter une fonction qui va permettre de construire ce tableau.

buildCommands: function () {
    if (SP.ScriptUtility.isNullOrUndefined(this.commands)) {
        this.commands = [];
        this.commands[this.commands.length] = 'RedoButtonClick';
    }

    return this.commands;
},

Nous commençons tout d’abord par vérifier que le tableau n’a pas encore été initialisé. Nous allons bien entendu utiliser le tableau « commands » déclaré précédemment. Pour vérifier la nullité d’un objet en JavaScript, SharePoint met à disposition une fonction nommée « isNullOrUndefined » qui va renvoyer « true » si l’objet est null ou « false » dans le cas contraire.

Si ce tableau n’est pas défini, nous le créons et nous lui ajoutons l’élément « RedoButtonClick ». Cet élément correspond à une commande que notre « Page Component » va pour intercepter. Si nous avons défini ce tableau, ce n’est pas pour rien. Effectivement, le « Ribbon » de SharePoint va appeler une fonction de notre « Page Component » pour connaitre ce tableau. Cette fonction se nomme « getGlobalCommands », nous allons donc devoir l’implémenter :

getGlobalCommands: function () {
    return this.buildCommands();
},

Ici, nous nous contentons simplement de renvoyer le tableau renvoyé par la fonction « buildCommands » que nous avons implémenté un peu avant. La chose à bien comprendre est que le Ribbon va automatiquement appeler cette fonction pour connaître le nom des fonctions que notre « Page Component » PEUT traiter. Autrement dit, dès que la commande « RedoButtonClick » sera exécutée, le « dispatcher » redirigera l’exécution du code dans notre « Page Component ».

Maintenant que nous avons rerouté le « dispatcher » dans notre « Page Component », nous allons devoir implémenter une fonction qui permet d’indiquer si le « Page Component » est capable de traiter la commande.

canHandleCommand: function (commandId) {

    var items = SP.ListOperation.Selection.getSelectedItems();

    if (SP.ScriptUtility.isNullOrUndefined(items) || items.length == 0)
        return false;

    return true;

},

Ici, il faut bien faire la différence entre le fait de « pouvoir recevoir la commande » et « être capable de traiter la commande ». Imaginons que notre bouton serve à supprimer des éléments. Nous pourrions indiquer au Ribbon que nous pouvons recevoir la commande « DeleteItem », ainsi, notre « Page Component » sera appelé. Cependant, si aucun élément n’est sélectionné, nous sommes dans l’impossibilité de supprimer l’élément, notre « Page Component » n’est donc pas capable de traiter la commande. Cependant, il est primordial qu’il soit informé que la commande a été lancée. Justement pour vérifier qu’un élément a été sélectionné ou non.

Pour en revenir à la commande « canHandleCommand », celle-ci va donc permettre d’indiquer si oui ou non elle peut traiter la commande en l’état actuel des choses. L’argument « commandId » est simplement le nom de la commande à traiter.

Nous récupérons d’abord une référence aux éléments sélectionnés dans la liste et la plaçons dans la variable « items ». Nous vérifions ensuite que cette variable n’est pas null et qu’au moins un élément a été sélectionné. Si ce n’est pas le cas, nous renvoyons « false », ce qui aura pour effet de griser le bouton. Par contre, si un élément a bien été sélectionné, nous renvoyons « true » pour activer le bouton.

Maintenant que nous avons défini la fonction permettant au Ribbon de savoir quelles commandes notre « Page Component » peut traiter et la fonction permettant d’indiquer si notre « Page Component » est capable de traiter la demande, nous allons implémenter la fonction permettant d’exécuter les commandes.

handleCommand: function (commandId, properties, sequence) {

    alert('The command "' + commandId + '" has been fired');
    return true;

}

Cette fonction sera automatiquement appelée si notre « Page Component » reçoit une commande et que celui-ci a renvoyé « true » dans sa fonction « canHandleCommand ». Le paramètre « commandId » est encore une fois le nom de la commande à traiter. « properties » contient certaines propriétés relatives à notre contrôle. Enfin « sequence » est l’ordre de la commande.

Notre « prototype » est maintenant terminé. Nous allons maintenant devoir créer quelques fonctions pour pouvoir enregistrer notre « Page Component » dans le Ribbon. La première de celle-ci va permettre de récupérer une instance de notre « Page Component ». Ici, nous allons nous baser sur le « Design Pattern » du « Singleton » pour être sûr de créer qu’une seule instance de notre « Page Component » :

MSDN.MyPC.PageComponent.get_instance = function () {

    if (SP.ScriptUtility.isNullOrUndefined(MSDN.MyPC.PageComponent.singleton))
        MSDN.MyPC.PageComponent.singleton = new MSDN.MyPC.PageComponent();

    return MSDN.MyPC.PageComponent.singleton;
}

Le « Design Pattern » du « Singleton », pour ceux qui ne connaissent pas, est assez simple. En gros, si un objet ne contient pas une référence, il va créer cet objet et le renvoyer, tout en le gardant en mémoire. Ainsi, quand nous allons devoir accéder de nouveau à cet objet, il suffira de renvoyer cette référence et non de la recréer. Cela permet d’être sûr qu’on ne crée pas plus d’une instance du même objet. Ici, nous regardons si l’objet « MSDN.MyPC.PageComponent.singleton » est null. Si c’est le cas nous le créons. Enfin, nous renvoyons cet objet.

Passons maintenant à la fonction qui va permettre d’ajouter notre « Page Component » à ceux du Ribbon.

MSDN.MyPC.PageComponent.registerWithPageManager = function () {
    SP.Ribbon.PageManager.get_instance().addPageComponent(MSDN.MyPC.PageComponent.get_instance());
}

Nous récupérons simplement l’instance du « Page Manager » grâce à son API et nous appelons sa fonction « addPageComponent » pour ajouter le nôtre. Nous faisons passer la référence à celui-ci pour l’enregistrer. Nous allons également implémenter une fonction permettant de retirer notre « Page Component ».

MSDN.MyPC.PageComponent.unregisterWithPageManager = function () {
    if (SP.ScriptUtility.isNullOrUndefined(MSDN.MyPC.PageComponent.singleton) == false)
        SP.Ribbon.PageManager.get_instance().removePageComponent(MSDN.MyPC.PageComponent.get_instance());
}

Ici, nous vérifions d’abord que l’objet « singleton » n’est pas « null ». Effectivement, seule la fonction « registerWithPageManager » crée une référence à notre « Page Component », donc si cette référence n’existe pas, c’est que notre « Page Component » n’a pas été ajouté au Ribbon. Dans le cas contraire, nous appelons la fonction « removePageComponent » du « Page Manager » pour retirer notre « Page Component ».

Nous allons maintenant exécuter cette instruction pour enregistrer la classe que nous venons de créer :

MSDN.MyPC.PageComponent.registerClass("MSDN.MyPC.PageComponent", CUI.Page.PageComponent);

La fonction « registerClass » est définie dans la classe « Type » et permet d’enregistrer notre classe comme étant un « Page Component » (deuxième paramètre). Ensuite, nous appelons notre fonction « registerWithPageManager » pour ajouter notre « Page Component » au « Ribbon ».

MSDN.MyPC.PageComponent.registerWithPageManager();

Tapez également l’instruction suivante :

NotifyScriptLoadedAndExecuteWaitingJobs("MSDN.MyPC.js");

Cette fonction n’est en rien obligatoire, mais elle permet simplement de notifier que notre « Page Component » a fini de se charger (au cas où d’autre fichier JavaScript attendrait cela pour s’exécuter).

Voilà, notre « Page Component » est terminé. Avant de l’installer, nous devons référencer notre fichier « JavaScript » dans la « Master Page » de SharePoint. Nous pouvons soit le faire via « SharePoint Designer » ou alors, utiliser les « Delegate Control ». Nous allons utiliser la deuxième méthode.

Création du Delegate Control

Pour cela, nous allons devoir créer un « User Control » que nous allons insérer dans le « Delegate Control ». Faites donc un clic droit sur votre projet et choisissez Add > New > SharePoint Mapped Folder. Dans la fenêtre qui s’affiche, déroulez le dossier « TEMPLATE » et choisissez le dossier « CONTROLTEMPLATES ». Faites ensuite un clic droit sur le dossier contenu dans le dossier mappé, choisissez Add > New Item > User Control et nommez-le « MSDN.MyPC.DelegateControl.ascx ». Supprimez le fichier « MSDN.MyPC.DelegateControl.ascx.cs », ouvrez le fichier « ascx » et remplacez son contenu par :

<script language="javascript" src="/_layouts/MSDN.MyPC/MSDN.MyPC.js"></script>

Cet « User Control » contient simplement une référence « JavaScript » vers notre fichier. Enfin, nous allons devoir insérer ce contrôle dans le « Delegate Control » des « header ». Pour cela, ouvrez votre fichier « Elements.xml » et ajoutez la ligne suivante :

<Control Id="AdditionalPageHead" Sequence="80" ControlSrc="~/_ControlTemplates/MSDN.MyPC.DelegateControl.ascx" />

Cela permet simplement d’insérer notre « User Control » dans le « Delegate Control AdditionalPageHead » qui se trouve dans la balise « head » de la page. Vous pouvez maintenant déployer et tester votre programme.

Déploiement et test

Rendez-vous donc sur une liste générique et afficher l’onglet « Items ».

05

Etant donné qu’aucun élément n’a été sélectionné, notre contrôle n’est pas disponible. Maintenant, si vous sélectionnez un élément :

06

Enfin, si vous cliquez sur votre bouton :

07

La commande est bien exécutée.

Debuging

Avant de clôturer ce tutoriel, j’aimerai juste attacher le débuggeur à l’exécution de notre code JavaScript pour bien voir les fonctions qui sont exécutées. Placez donc des points d’arrêts aux différentes fonctions de notre fichier JavaScript.

08

Exécutez ensuite votre projet en appuyant sur F5 et rendez-vous sur une liste générique. La commande « init » va alors être exécutée car notre « Page Component » va être ajouté au Ribbon de la liste générique. La fonction « getGlobalCommands » a également été exécuté permettant ainsi de renseigner le « dispatcher » sur les commandes que peut intercepter notre « Page Component ».

Allez maintenant dans l’onglet « Items ». Cette fois, c’est la commande « canHandleCommand » qui est appelée. Effectivement, la fonction « getGlobalCommands » a indiqué au « Ribbon » que notre « Page Component » peut traiter la commande « RedoButtonClick ». Donc, quand le bouton va être affiché, le Ribbon va automatiquement appeler la fonction « canHandleCommand » de notre « Page Component ». Si vous regardez les variables globales au moment de l’exécution, vous verrez ceci :

09

La valeur de l’argument « commandId » est bien « RedoButtonClick ». Et vous pouvez remarquer que cette fonction n’est appelée que pour cette commande. En effet, le « dispatcher » n’appelle pas notre « Page Component » pour toutes les commandes lancées par le Ribbon, justement parce que la fonction « getGlobalCommands » a indiqué quelles commandes notre « Page Component » peut traiter.

Sélectionnez ensuite un élément. Encore une fois, la fonction « canHandleCommand » est appelée, mais cette fois, étant donné qu’un élément est sélectionné, elle renvoie « true ». Ainsi, lorsque nous cliquons sur notre bouton, la fonction « handleCommand » est exécutée et le nom de la commande est passé en paramètre.

Voilà, cette fois, c’en est bien fini de ce cours. Celui-ci vous a expliqué comment faire un « Page Component » simple. Dans le prochain article, nous verrons comment faire un « Page Component » plus évolué pour, par exemple, remplir un « Split Button » dynamiquement.

Vous pouvez télécharger les sources de l’exemple expliqué dans ce cours à l’adresse :
http://download.microsoft.com/download/7/B/2/7B245E86-4174-4B99-B7F8-8E4E7CF27C31/MSDN_MyPC.zip

Sébastien Sougnez
(MVP Sharepoint)

Je me nomme Sébastien Sougnez et je suis le Web Master du site http://www.areaprog. J’ai commencé la programmation en l’an 2000 en Visual Basic 6.0. Au fil des années, je me suis formé dans d’autres langages pour au final me spécialiser dans le SharePoint. J’ai d’ailleurs décidé de partager mes connaissances sur AreaProg et sur d’autres sites tels que http://www.developpez.com, MSDN,… Depuis Juillet 2010, je suis devenu MVP SharePoint.

Ressources SharePoint

Développement de récepteurs d’événements

Dans SharePoint 2010, les récepteurs d’événements permettent d’exécuter du code lorsqu’une action spécifique se produit sur le serveur. Il existe un grand nombre d’événements pour lesquels on peut développer un récepteur d’événements.

Développement d'un page component simple pour intercepter les commandes d'un bouton personnel du Ribbon

Pour ajouter des éléments dans le « Ribbon », une technique utilisée consiste à développer des « custom actions ». Dans le code de celles-ci, nous insérons directement le code « JavaScript » nécessaire au traitement du bouton dans le fichier XML de déclaration.

Microsoft TechDays 2010 - Vidéos autour du développement SharePoint 2010

Regardez ces vidéos et découvrez ce qui se cache derrière SharePoint 2010..

Centre pour développeurs SharePoint 2010

Retrouvez des informations de mise en route essentielles, des nouveautés et des ressources d'apprentissage pour développeurs.

Open XML SDK 2.0 pour Microsoft Office (RTM)

Créez des solutions de génération de documents haute performance côté client ou côté serveur avec ce SDK.

Galerie de code

Recherchez les exemples de code de développement SharePoint les plus récents ou téléchargez les vôtres.

CodePlex

Recherchez des projets open source sur CodePlex ou démarrez le vôtre.

Microsoft réalise une enquête en ligne pour comprendre votre opinion sur le site Web de. Si vous choisissez de participer, l’enquête en ligne vous sera présentée lorsque vous quitterez le site Web de.

Souhaitez-vous y participer ?