[SharePoint 2010] Erreur SP.UI.ModalDialog : object doesn't support this property or method

Publié le 11 juillet 2011 par Nicolasesprit

Dans un WebPart SharePoint 2010 j'ai voulu rajouter un lien permettant d'ouvrir un pop-up. L'idée étant que le WebPart affiche des données et que l'utilisateur puisse les modifier via ce modal pop-up. Jusque là pas de soucis, un appel à la librairie javascript SharePoint et plus précisément SP.UI.ModalDialog.showModalDialog suffit.

Là où cela se complique, c'est lorsqu'on souhaite que ce pop-up s'affiche automatiquement au chargement de la page si les données n'ont pas encore été saisies par l'utilisateur. Utilisant un Visual WebPart j'ai ceci dans mon markup (de manière simplifiée) :

<script type="text/javascript">
function OpenMonPopUp(_url) {
var options = {
url: _url,
width: 800,
height: 600
};
SP.UI.ModalDialog.showModalDialog(options);
}
</script>
...
<a id="lnkEdit" runat="server">Edit Fund</a>
...

Dans le code-behind de mon WebPart, si les données ne sont pas saisies (le booléen MaCcondition) alors je fais appel à RegisterStartupscript pour appeller simplement ma méthode javascript OpenFund qui fonctionne très bien :

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string url = SPContext.Current.Web.Url + "/_layouts/MonWebParts/MonApplicationPage.aspx";
lnkEdit.HRef = string.Format("javascript:OpenMonPopUp('{0}')", url);
if (MaCondition)
{
string monScript = string.Format("OpenMonPopUp('{0}');", url));
ScriptManager.RegisterStartupScript(this, this.GetType(), "keyOpenMonPopUp", monScript , true);
}
}
}

Et là c'est le drame, lors du chargement de la page contenant le WebPart j'obtiens cette erreur javascript lors de l'appel à SP.UI.ModalDialog.showModalDialog :

object doesn't support this property or method

Le problème ne provient pas de ma méthode OpenMonPopUp ni d'un oubli de référence au script SharePoint SP.js. Alors quoi ? En fait, le problème est simple : mon appel à SP.UI.ModalDialog.showModalDialog et donc à la librairie SP.js via RegisterStartupScript se fait AVANT le chargement de la dite librairie. La solution est tout aussi simple : utiliser la méthode javascript ExecuteOrDelayUntilScriptLoaded afin d'attendre le chargement de la librairie. Ce qui donne au final :

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string url = SPContext.Current.Web.Url + "/_layouts/MonWebParts/MonApplicationPage.aspx";
lnkEdit.HRef = string.Format("javascript:OpenMonPopUp('{0}')", url);
if (MaCondition)
{
StringBuilder sb = new StringBuilder();
sb.Append("ExecuteOrDelayUntilScriptLoaded(function () {");
sb.Append(string.Format("OpenMonPopUp('{0}');", url));
sb.Append("}, \"sp.js\");");

ScriptManager.RegisterStartupScript(this, this.GetType(), "keyOpenMonPopUp", sb.ToString(), true);
}
}
}

Hope this help !