Bonjour à tous,
Aujourd’hui je suis tombé sur un « bug » (ou du moins comportement de SharePoint) assez étrange.
On m’avait demandé de coder un custom field type pour un client qui affichait la sécurité courante de l’item. Jusque-là tout fonctionnait bien, rien de très difficile, si ce n’est que quand le client ajoutait le champ à une liste (via create column par exemple), il n’apparaissait pas dans la liste des colonnes de la liste.
Assez embêtant pour renommer la colonne vous me direz ou encore pour la supprimer. Je suis assez d’accord.
J’ai commencé, comme tout bon développeur, par chercher des cas similaires sur internet, de la doc, et il n’y avait pas grand-chose sur le sujet donc après avoir trouvé la solution j’ai décidé de la partager.
Donc après n’avoir rien trouvé sur Internet, je me suis décidé à regarder comment SharePoint fonctionnait. N’hésitez pas à le faire quand vous manquez de documentation, si Microsoft avait voulu cacher le code ils auraient pu le faire, le tout est de ne pas publier/réutiliser leur code.
Je me commence donc par aller chercher la page qui me pose problème pour ensuite retomber sur les assemblies qui m’intéresseront et là, surprise, tout est en code inline ! On est très loin des recommandations de Microsoft sur le code behind, qui facilite le débug, qui est plus performant etc etc. Allez y faire un tour c’est instructif {14hive}\TEMPLATE\layouts\listedit.aspx
Sans surprise on se rend compte que le code d’affichage se base de nombreux tests sur le type et des propriétés des champs. Et que notre nouveau type de champ ne faisant pas partie de l’énumération SPFieldType, il passe un peu à la trappe.
J’ai pu identifier trois cas canoniques qui nous intéressent :
Soit votre type de champ fait aussi de la saisie (enregistre des données), il s’affiche normalement dans cette liste de colonnes
Soit votre type de champ est en readonly (définit via sa class dérivant de SPField), et la propriété XPath est null, il ne s’affiche pas
Soit votre type de champ est en readonly et la propriété XPath est définie (même à string.empty), il s’affiche dans la liste de colonnes, mais pas de lien (ce qui est cohérent puisqu’il est en readonly)
Maintenant comment faire si comme moi vous voulez un type de champ dans lequel les utilisateurs ne puissent pas rentrer de données, mais qu’ils puissent le supprimer/renommer (et donc l’avoir dans la liste des colonnes de la liste) ?
C’est simple (et incongru) mais il ne faut pas le mettre en readonly, il faut se servir des propriétés showin… (celles de la classe dérivant de SPField) et les mettre à false (enfin sauf ShowInListSettings hein).
Autre astuce, pendant vos tests, ces propriétés ne sont prises en compte que lorsque vous ajoutez/ supprimez le champ à vos colonnes dans une liste (donc une mise à jour de l’assembly + du fldtype + iireset /noforce ne suffisent pas), merci à Pascal Bonheur mon technical lead qui m’a fait remarquer ça alors que je n’étais pas très réveillé (et que je venais de faire une heure d’investigations à blanc)
Voilà j’espère que cette information fera gagner du temps à nombre d’entre vous sur cette problématique.
PS: si quelqu’un sait à quoi sert la propriété XPath qui n’est pas documentée je suis preneur.
PPS : à ce qui se demandent pourquoi j’ai besoin d’un type de champ juste pour faire de l’affichage, j’affiche la sécurité courante de l’élément, qui ne fait malheureusement partie des données dont on dispose dans un xslt de rendu. Du coup si je ne veux rien stocker/pré-calculer je suis obligé de passer par ça.