SP2010–Remplacer les formulaires–Part 2

Posted on Updated on

Bonjour à tous.

Dans la partie précédente, nous avons vu comment créer trois modèles de listes SharePoint 2010 (fonctionnera également avec 2007 et 2013, Server ou Foundation). Avec ces modèles nous avons déployé pour chacun d’eux une instance : Pays, Villes et Commandes.

Le tout bien sûr “packagé” dans une solution SharePoint avec Visual Studio 2010. Ainsi nous avons utilisé une “Feature” pour déployer le tout qui, lorsqu’elle s’active, déploie les modèles, créée les instances de ces listes et remplit les listes Pays et Villes avec un ensemble de données.

Dans cette nouvelle partie, nous allons tenter de remplacer les formulaires standards :

  • DispForm.aspx
  • NewForm.aspx
  • EditForm.aspx

Dans le but de surcharger leur comportement, principalement au niveau des listes déroulantes : la liste des villes disponibles sera filtrée en fonction du pays qui sera sélectionné.

Pour compléter, vous pourriez également faire appel à quelques projets CodePlex fournissant ces listes déroulantes liées par le biais de champs personnalisés (Custom Fields) qui sont réutilisables et en soit plus “propres”. Je vous propose une autre méthode, sans passer par ces fonctionnalités additionnelles, plus dans le cas d’un usage unique.

1/ Comprendre la structure – le pourquoi…

Avant d’entamer la phase technique du développement/déploiement, il est essentiel de comprendre comment fonctionnent les formulaires standards, où ils sont déployés, etc.

Vous pouvez utiliser SharePoint Manager 2010 ou SharePoint Designer 2010 pour explorer la structure utilisé par les listes pour rediriger l’utilisateur vers ces fameux formulaires lorsqu’il souhaitera ajouter/modifier/voir les propriétés d’un élément/document dans une liste/bibliothèque de documents SharePoint. La structure est plutôt simple. Elle se compose de :

  • Un répertoire racine : RootFolder. Ce répertoire est créé par défaut.
  • Des sous-répertoires créés par les utilisateurs
  • Des items/documents créés par les utilisateurs
  • Un répertoire particulier : “Forms” qui contient les formulaires en question pour les bibliothèques de documents
  • Pour les listes, les formulaires en questions sont placés directement dans le RootFolder.

0102

Il m’est arrivé, bien souvent, de reprendre des projets SharePoint, par les biais de missions de conseil, d’assistance et je vois assez régulièrement des développeurs ayant essayé de “surcharger” ces formulaires en créant leurs propres formulaires (par copier/coller)… ayant des nom différents. Et en général… :

  • DispForm.aspx devient DisForm2.aspx
  • NewForm.aspx devient NewForm2.aspx
  • EditForm.aspx devient EditForm2.aspx

Et moi…. ça ne me convient pas ! En effet, les anciens formulaires restent disponibles, ils ne sont pas masqués… et restent donc accessible pour quelqu’un d’observateur qui saura assez rapidement appeler ces url et pourra donc se passer des règles de gestion que l’on souhaite imposer. Nous allons voir maintenant comment écraser ces fichiers standards en déployant notre solution SharePoint et les associer à nos listes Villes et Commandes.

2/ Déployer des Formulaires personnalisés

Reprenons notre solution. On remarque tout de suite que nous n’avons aucun fichier “aspx” dans les répertoires de la solution (répertoires des listes en particulier).

Première manipulation : utiliser SharePoint Designer 2010 pour récupérer les fichiers “aspx” originaux.

On commence donc par lancer SharePoint Designer 2010 (de préférence en 32bits Clignement d'œil), on se connecte donc sur le site et utilise l’explorateur pour atteindre notre liste, Villes par exemple (via l’explorateur à gauche “All Files > Lists > Villes”) :

image

03

On remarque tout de suite la présence des fichiers qui nous intéressent. Manipulation assez simple, on ouvre chacun des fichiers (en mode Avancé : clic droit sur chaque fichier > Ouvrir en mode avancé) et on copie/colle le contenu de chacun dans un fichier (avec Notepad ou autre) le but étant de sauvegarder chacun de ces fichiers dans le répertoire de la solution, à l’intérieur du dossier concernant notre liste et bien sûr avec le nom qui va bien… :

04

On copie le contenu du fichier…

05

Dans un Notepad :

06

On sauvegarde dans les répertoires Windows des définitions des listes Villes et Commandes, puis on inclut les fichiers dans la solution SharePoint :

07

Les nouveaux fichiers sont inclus :

08

Il reste ensuite une dernière manipulation à faire, sur chacun de nos fichiers aspx ajoutés dans la solution, nous allons faire un clic-droit > Propriétés :

09

Et nous allons changer la propriété “Deployment Type” en “ElementFile” (on peut vérifier le répertoire de déploiement qui doit pointer vers le répertoire de sortie de la feature dans le répertoire 14 (SharePointRoot) :

10

On reproduit ceci sur chacun des fichiers aspx. Vous pouvez vérifier dans le fichier “SharePointProjectItem.spdata” (celui au niveau de la déclaration du modèle de liste) que les modifications ont bien été apportées :

11

Notre solution est donc enrichie avec ces nouvelles pages. Toutefois, si l’on déploie ces nouvelles pages aspx directement, l’instance déployée n’utilisera pas directement nos nouvelles pages. Pour cela, nous allons devoir modifier le fichier Schema.xml pour chacune de ces listes, au niveau du nœud “Forms” (tout à la fin du fichier) :

<Forms>
<Form Type=”DisplayForm” Url=”DispForm.aspx” SetupPath=”pages\form.aspx” WebPartZoneID=”Main” />
<Form Type=”EditForm” Url=”EditForm.aspx” SetupPath=”pages\form.aspx” WebPartZoneID=”Main” />
<Form Type=”NewForm” Url=”NewForm.aspx” SetupPath=”pages\form.aspx” WebPartZoneID=”Main” />
</Forms>

Chaque formulaire/page est associé à notre liste SharePoint par le biais d’un nœud <Form />.

Nous allons modifier chacun de ces nœuds <Form /> pour indiquer à SharePoint qu’il doit utiliser nos pages et pas celles par défaut. Nous allons donc supprimer l’attribut SetupPath pour faire pointer chacun des formulaires vers nos pages custom.

Nous allons également ajouter quelques attributs :

  • Path=”NewForm.aspx” => Chemin relatif vers le fichier NewForm.aspx dans notre solution
  • Default=”TRUE” => Page par défaut
  • UseDefaultListFormWebPart=”False” => Ne pas utiliser le WebPart Standard
  • WebPartOrder=”1″ => Le WebPart sera placé en premier dans la zone de WebParts (il n’y en aura qu’un dans la page de toute manière)

Ce qui donne :

<Form Type=”NewForm” Url=”NewForm.aspx” Path=”NewForm.aspx” WebPartZoneID=”Main” Default=”TRUE” UseDefaultListFormWebPart=”False” WebPartOrder=”1″>

</Form>

Nous allons ensuite ajouter le WebPart de type ListFormWebPart dans la page NewForm.aspx pour afficher le formulaire standard. Il existe plusieurs méthodes que vous retrouverez sur Google, Bing ou autre.

Pour ma part, je vais choisir une méthode moins traditionnelle qui consiste à placer ce WebPart directement dans la déclaration de l’association du formulaire d’ajout d’élément et notre page custom (toutes les méthodes sont possible, celle-ci n’est pas meilleure !… juste différente). Nous allons ajouter un tag <WebParts> directement dans le <Form/> précédent, qui contiendra la déclaration du WebPart de type ListFormWebPart. Certains ont déjà du croiser ce type de déclaration, très utilisé lorsqu’on déploie des pages web avec des Modules. On obtiendra :

<Forms>

<Form Type=”NewForm” Url=”NewForm.aspx” Path=”NewForm.aspx” WebPartZoneID=”Main” Default=”TRUE” UseDefaultListFormWebPart=”False” WebPartOrder=”1″>
<WebParts>
<AllUsersWebPart WebPartZoneID=”Main” WebPartOrder=”1″>
<![CDATA[
<WebPart xmlns=”http://schemas.microsoft.com/WebPart/v2″>
<Assembly>Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
<TypeName>Microsoft.SharePoint.WebPartPages.ListFormWebPart</TypeName>
<PageType>PAGE_NEWFORM</PageType>
</WebPart>]]>
</AllUsersWebPart>
</WebParts>
</Form>
</Forms>

On déclare ici un WebPart de type Microsoft.SharePoint.WebPartPages.ListFormWebPart dans la zone “Main”. Notez également le tag PageType qui a la valeur PAGE_NEWFORM indiquant qu’il s’agit bien de ce WebPart dans le mode de rendu “New” (nouvel élément). Vous trouverez ici les valeurs possibles pour cette énumération : http://msdn.microsoft.com/fr-fr/library/microsoft.sharepoint.pagetype(v=office.12).aspx

On reproduit cela pour chacun des formulaires, sur nos listes Villes et Commandes :

18

Mais me direz-vous, nous avons copié les pages NewForm, DispForm et EditForm avec SharePoint Designer et ce WebPart devrait être déjà présent dans les pages… Oui tout à fait, c’est pour cela que nous allons le supprimer !

On ouvre donc un à un chacun des fichiers NewForm.aspx, EditForm.aspx et DispForm.aspx (pour les listes Villes et Commandes) et on recherche :

<WebPartPages:ListFormWebPart runat=”server” __MarkupType=”xmlmarkup” ……… </WebPartPages:ListFormWebPart>

On sélectionne le tout et on supprime tout le contenu de cet élément (l’élément y compris) :

19

On sauvegarde le tout.

Pour préciser pourquoi on ne conserve pas ce WebPart dans les pages, vous avez peut être remarque qu’il possédait la propriété ListId. Malheureusement, cette propriété est valorisée avec un GUID qui représente l’identifiant unique de la liste… et qui sera différent à chaque redéploiement de notre Solution. Impossible donc de packager ce composant directement avec le bon GUID. Vous pourrez par contre utiliser l’attribut ListName valorisé avec l’url relative de la liste.

Il nous reste à compiler, déployer… Pour vérifier que les fichiers sont bien déployés et écrasent bien les fichiers natifs, il faut changer un peu le contenu de la page (le bon vieux test du TOTO dans la page Clignement d'œil)…

Pour cela, j’ai choisi le formulaire NewForm.aspx de la liste de Commandes. Dans le ContentPlaceHolder “PlaceHolderPageTitle”, j’ajoute un TOTO :

20

On compile avec Visual Studio et on déploie sur notre plateforme SharePoint. Une fois le tout déployé, je me dirige vers ma liste de Commandes dans le navigateur, je clique sur nouveau :

21

On retrouve bien le TOTO dans le titre de la fenêtre !!! (Bien sûr on supprime le TOTO Sourire et on redéploye).

Ca c’est fait.

3/ Modifier le comportement des pages

Nos pages étant maintenant déployées, nous allons modifier leur héritage natif pour les faire hériter de classes contenues dans notre propre assembly (DLL). Pour cela, nous allons créer une classe C# pour chacun des pages NewForm, DispForm & EditForm, et ce pour chacune de nos listes (donc 6 classes dans mon cas).

En général, je créé un répertoire Pages à la racine de mon projet (les pages sont compilées dans la DLL et le fichier .cs n’est pas déployé). Une fois le dossier créé, j’ajoute 6 classes :

14

15

Ensuite, nous allons faire hériter chacune de ces classes de “WebPartPage” et ajouter “using Microsoft.SharePoint.WebPartPages” :

16

Ensuite, dans chacune des pages aspx, nous allons :

  • Ajouter tout au début :  <%@ Assembly Name=”$SharePoint.Project.AssemblyFullName$” %>
  • Modifier le Inherits pour pointer vers notre assembly :

Inherits=”Microsoft.SharePoint.WebPartPages.WebPartPage,Microsoft.SharePoint, Version=14.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c”

devient

Inherits=”DEMO1.Pages.CommandesNewForm,$SharePoint.Project.AssemblyFullName$”

Où :

  • DEMO1.Pages.CommandesNewForm = Namespace + nom de la classe
  • $SharePoint.Project.AssemblyFullName$ : nom complet de l’Assembly, valorisé par Visual Studio avant le déploiement.

On recommence la manipulation sur chacune des 6 pages aspx:

22

On compile/déploie à nouveau le tout. Pour tester que le code-behind est bien appelé, on peut passer en debug sur la solution et vérifier que la méthode OnLoad() est bien appelée :

23

Et voilà !

Je me décide enfin à publier cet article…, je continuerai la suite un peu plus tard ! Au programme, personnalisation du comportement des formulaires !

Wait & see (pas trop longtemps j’espère Sourire) !

6 thoughts on “SP2010–Remplacer les formulaires–Part 2

    Rodrigue said:
    20 March 2013 at 11:23

    Merci pour ce tuto Florent!
    C’est vrai que les tutos que j’ai vu proposaient tous de dupliquer le formulaire et je trouvaient cette façon assez dégueulasse!
    J’attaque mon premier projet Sharepoint à partir de la semaine prochaine pour le centre Pompidou à Paris et ton tuto me sera bien utile 🙂
    A bientôt,
    Rodrigue

    Rodrigue said:
    20 March 2013 at 11:25

    Rodrigue :
    Merci pour ce tuto Florent!
    C’est vrai que les tutos que j’ai vu proposaient tous de dupliquer le formulaire et je trouvais cette façon assez dégueulasse!
    J’attaque mon premier projet Sharepoint à partir de la semaine prochaine pour le centre Pompidou à Paris et ton tuto me sera bien utile
    A bientôt,
    Rodrigue

      Florent Cazenave responded:
      20 March 2013 at 13:56

      Excellent, enfin du SharePoint ! lis bien tous mon blog et ceux de la communauté, ça t’aidera bien !

      A bientot !! ++

    Marouene KAROUI said:
    28 November 2014 at 17:47

    ReBonjour, et merci aussi pour cette 2ème partie, ce qui m’amène à vous demander la 3ème partie 🙂
    Si je veux par exemple customiser les affichages (pre-remplir les colonnes selon l’utilisateur connecté) ou bien générer les accès et les affichages, ….
    cacher ou pas un des champs de la liste …

    Est ce que c’est possible de générer le contenu des formulaires (au lieu de laisser SharePoint auto-générer),
    Je suis presque sur que vous avez déjà abordé la question quelque part pouvez vous alors m’orienter vers un de vos tutos,

    Encore Merci

    Marouene KAROUI said:
    28 November 2014 at 17:49

    * gérer les accès et les affichages*

    Florent Cazenave responded:
    28 November 2014 at 18:24

    Oui en fait… effectivement je n’ai pas traité la partie 3 ! (TODO !).
    En fait, cela revient à ce moment là à faire de l’ASP.Net, et plus vraiment du SharePoint.
    Du moment que vous accès au code behind (comme sur la dernière image), il suffit de déclarer vos controles (ASP.Net ou SharePoint) dans le code du formulaire aspx et d’implémenter le comportement du formulaire. Vous pouvez le faire coté serveur, avec des postbacks de pages ou avec un peu d’ajax ou même du Javascript !
    Vous pouvez aussi fouiller du coté des rendering template, des listfieldIterator… par exemple : http://sharepointera.blogspot.fr/2012/08/how-to-add-extra-functionality-to_23.html

    Florent.

Leave a comment