Lors du précédent billet, je vous ai rapidement présenté une utilisation basique des CustomActions.
Mais si on veut aller plus loin, on découvre que l'on peut utiliser ses propres WebControl lorsqu'on souhaite rajouter des menus dans SharePoint. Ca laisse reveur ...
Ce post va donc vous présenter le genre de personnalisation que l'on peut obtenir avec cette méthode.
L'idée de départ est simple : je souhaite pouvoir lancer le plus simplement possible un workflow spécifique sur l'ensemble des éléments de ma liste. Comment faire ? la preuve en images.
- Présentation de la solution :
Ce projet comprend une feature, une page qui sera déployer dans les layouts et un peu code que nous allons détaillé par la suite.
- Creation de la CustomAction
Ici, je souhaite rajouter un nouveau menu au niveau de la boite à outil de ma liste dans la menu Action. Je souhaite que mon menu n'apparaisse uniquement que sur les listes (RegistrationType=List) de type librairie de document (RegistrationId=101).
- Creation du WebControl associé
On va créer une nouvelle Classe qui va hériter de WebControl. Jusqu'ici que du classique.
L'ensemble du "vrai" travail, se fait dans la méthode CreateChildControls. Nous allons tout simplement rajouter un nouveau control de type SubMenuTemplate qui va nous permettre de rajouter un MenuItemTemplate pour chaque Workflow associé à la liste.
On récupère les workflows associés à la liste via WorkflowAssociations et on s'assure que le workflow peut être lancé (Enabled, AllowManual à True).
L'utilisation de la méthode FindListView() est une astuce développée par TheKid qui permet de circonvenir un bug avec le token {ListId} qui n'est pas forcément transformer à l'éxécution de la réquête. Plus de détails à cette adresse : http://blog.thekid.me.uk/archive/2008/04/29/sharepoint-custom-actions-in-a-list-view-webpart.aspx
Voilà la méthode en question :
Il ne reste plus qu'à déployer, compiler et voilà le résultat. Je sais , j'aurais pu faire un effort au niveau du désign ;) :
Maintenant, il ne nous reste plus qu'à sélectionner les éléments que l'on souhaite soumettre au Workflow. Pour faire au plus simple, j'ai choisi de faire cette action dans une page générique que j'aurais déployé dans les layouts.
- Rajout de la page qui va se charger de lancer le workflow sur chaque élément sélectionné
Rien de transcendant ici, on ajoute simplement une CheckBoxList à cette page "type". Vous pourrez retrouver comment faire des formulaires qui gardent le "look" SharePoint sur le livre "Inside WSS 3.0" de Ted Pattison. J'en reparlerais sans doute dans les prochains posts.
A noter simplement, que cette page fait appel à l'assembly Phil.SharePoint.Workflow.CustomMenu.RunSelectedWorkflowForm dont le code est détaillé ci-dessous.
Ici, on va travailler essentiellement sur la CheckBoxList, la liste d'élément et l'objet WorkflowAssociation
On récupère les paramètres passé dans l'URL (ListId et WFAssociationId) et on remplie la CheckBoxList.
Ce qui est un peu particulier ici est qu'il est nécessaire de faire tout un tas de vérification afin de ne pas pouvoir lancer le workflow sur un élément qui a déjà ce workflow en cours. C'est à cela que nous sert le SPFieldWorkflowStatus.
Ici, cette méthode lancera le workflow pour chaque élément sélectionné via la méthode StartWorkflow du WorkflowManager du site. A noter que l'on ne passe pas d'InstanciationData, ce qui peut être peu pratique pour certains workflows. Ce cas serait a traiter à l'occasion.
La gestion des erreurs de workflow "copié-collé" du livre de Ted Pattison.
Au final, la page donne ceci :
Voilà, j'espère vous avoir démontrer qu'il pouvait se révéler très intéressant de personnaliser l'interface SharePoint via les CustomAction et que grâce à l'utilisation de l'attribut ControlClass, les possibilités sont infinies :)
PS : Pour ceux qui se disent que j'aurais pu faire un copier coller de VisualStudio plutôt que des captures d'écrans. Je suis passé sous Hyper-V et Windows Serveur 2008, du coup je galère un peu pour la configuration de l'ensemble et jusqu'à présent je ne sais pas copier de ma VPC vers mon PC et j'ai quelques soucis pour échanger des fichiers entre les deux :).
<Philippe/>