Rich Text Editor (RTE) et code réentrant dans un contexte de Minimal Download Strategy (MDS)
Contexte
Vous avez généré sur votre environnement SharePoint 2013 une solution Visual Studio de type Visual Web Part et cette solution comporte un élément UpdatePanel (AJAX Extensions) ainsi qu’un élément InputFormTextBox (Microsoft.SharePoint.WebControls.InputFormTextBox).
Cette solution pourrait avoir la forme suivante :
L’intérêt du contrôle <asp:Button ID="btn" runat="server" Text="Refresh Panel" OnClick="btn_Click"/> est de pouvoir déclencher un post de la page et de mettre en évidence le fonctionnement présenté dans cet article de blog. Le code « behind » de ce contrôle pourrait effectuer l’action suivante :
Au final la page affichée par SharePoint pourrait avoir la forme suivante :
Un clic sur le bouton « Refresh Panel » aura l’effet suivant :
Le contrôle RTE ainsi que la barre d’outils sont dupliqués, le contenu est perdu et le contrôle devient non opérationnel.
Résolution
Des informations complémentaires sur ce comportement sont données dans le paragraphe « Conclusion ».
Depuis SharePoint 2013, un nouveau mode de rendu des pages ASPX est proposé, nommé « Minimal Download Strategy ». Cette fonctionnalité accélère le rendu d’une page lorsque peu d’éléments changent sur cette page. Dans ce contexte, les contrôles utilisés sur la page doivent pouvoir être rappelés. En d’autres termes, le code de l’élément doit être fonctionnel en mode réentrant. Dans l’exemple ci-dessus, nous voyons très bien que l’élément InputFormTextBox présente un dysfonctionnement dans un tel contexte.
Pour contourner ce fonctionnement, l'idée est de vérifier si l'élément est déjà sur la page lors de son appel pour affichage. Si tel est le cas il faut bloquer cet appel.
Voici, ci-dessous, quelques méthodes permettant de mettre en place ce contournement :
Premier exemple, dans une simple page ASPX
Dans un tel contexte, le code suivant, ajouté dans une page ASPX, serait suffisant :
Deuxième exemple, dans le cadre de notre web-part
Dans ce cas, cela se complique un peu. En effet, la fonction document.getElementById, pour pouvoir être utilisable, va nécessiter de fournir le ClientID du contrôle recherché sur la page ASPX.
Première solution
Il faut récupérer le ClientID du contrôle en éditant le code source de la page dans IE. La contrainte ici est que si la page est modifiée, alors le ClientID va changer. Il sera nécessaire de recompiler la solution Visual Studio et la redéployer.
Le code aurait la forme suivante :
Deuxième solution
Cette solution semble plus optimale pour contourner ce comportement. Elle consiste à remplacer la fonction JavaScript exposée ci-dessus par la version suivante :
Dernière précision
Il n’est pas nécessaire d’ajouter le code ci-dessus directement dans le fichier ASCX de la solution Visual Studio. Ce code peut être injecté par la fonction suivante déclarée dans le fichier ASCX.CS de la solution Visual Studio.
Conclusion
Ce dysfonctionnement a été rapporté au groupe produit SharePoint. Leur décision a été de ne pas toucher au code source utilisé par l’élément Rich Text Editor. RTE existe depuis plusieurs versions de SharePoint et le modifier maintenant pourrait avoir des impacts inattendus sur des plateformes SharePoint déjà installées.
La solution de contournement exposée ci-dessus a été officialisé par le groupe produit SharePoint et la fourniture d’une solution sous forme de correctif est pour l’instant exclue des prochaines mises à jour SharePoint.
Je remercie Cédric Naudy pour la relecture de ce billet.
Yamine Taiëb