Modal dialog in SharePoint

Dopo parecchio tempo di inattività, riaggiorno il mio blog parlando di un argomento che ancora non avevo trattato, SharePoint.

Un prodotto emblematico di casa Microsoft, su cui da oltre 5 anni lavoro, alternando fasi di esaltazione a sconforto.

Sicuramente un prodotto maturato con il tempo che tra qualche mese vedrà il lancio della nuova versione 2016.

Ieri mi sono imbattuto in una avventura con le modal dialog di SharePoint 2010 (ahimè) all'interno di una web part solution.

Per avere una panoramica del contesto, la web part esegue tutte le operazione server-side, inserendo i dati inputati in liste tramite il Server Object Model.

La specifica era di creare una modal di conferma, che permetta all'utente di procedere solo se spuntato un determinato input check all'interno della modal, causando un post back alla pagina.
Risolvibile molto semplicemente con l'oggetto confirm return confirm("hai letto l'informativa?");, ma senza l'utilizzo del checkbox.

Ho voluto complicare le cose, bypassando l'utilizzo delle modal di JQuery UI, ma cercando di utilizzare quelle native di SharePoint.

MSDN mi ha fornito la documentazione necessaria per invocare le API.
https://msdn.microsoft.com/en-us/library/office/ff410058(v=office.14).aspx

Ho inizialmente costruito un div HTML contenente la definizione della modal dialog:

<div style="display:none">
    <div id="divInformativa">
        <div style="text-align:center;">
            <asp:Label ID="lbCondizioni" runat="server"></asp:Label>
            <input type="checkbox" id="chkCondizioni"
            onclick="chkCondizioni_click(this)" />
        </div>
        <br />
        <div style="text-align:center;">
            <input type="button" disabled=disabled value="Conferma" 
            id="btnConfermaInformativa"
            onclick="btnConfermaInformativa_click()" />

            <input type="button" value="Esci" id="btnEsci"
            onclick="btnEsci_click()" />
        </div>

    </div> 
</div>

Quindi i metodi legati alla modal dialog.

var continueSubmit = false;
function showInformativa(sender) {
    if (!continueSubmit) {
        SP.UI.ModalDialog.showModalDialog({
            html: document.getElementById("divInformativa"),
            title: "Conferma lettura informativa",
            allowMaximize: false,
            height: 100,
            width: 400,
            showClose: false,
            dialogReturnValueCallback: function (result, target) {
                dialogInformativaResult(result, target, sender);
            }
        });
        return false;
    }
    else {
        showMessage('PRENOTAZIONE IN CORSO');
        return true;
    }
}

//Callback dialog
function dialogInformativaResult(result, target, sender) {
    if (result == SP.UI.DialogResult.OK) {
        continueSubmit = true;
        document.getElementById(sender).click();
    }
    if (result == SP.UI.DialogResult.cancel) {
        continueSubmit = false;
    }
}

//eventi sui button conferma ed esci
function btnConfermaInformativa_click() {
    SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.OK);
}
function btnEsci_click() {
    SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.cancel);
}

Tutto funziona al primo giro, ma solo al primo (!!!!????). Come mai? tentando di aprire la dialog una seconda volta, nella console compare un errore che indica la mancanza dell'elemento HTML di riferimento divInformativa.
Che strano!!

In effetti analizzando il DOM, appena viene invocato il metodo showModalDialog sparisce tutta la definizione della modal, provare per credere!

Come risolvere?, semplice copiando runtime una nuova definizione dell' HTML della modal in un altro oggetto nel DOM.

Ho aggiunto un div contenitore (nascosto) per appendere la definizione della modal.

<div id="divAppender" style="display:none"></div>

Ho eseguito quindi la copia dell'HTML della modal.

var divDialog = "<div id='modalDialogInformativa'>" +
document.getElementById("divInformativa").innerHTML + "</div>";

$('#divAppender').append(divDialog);

Risolto!
Mi rimane da provare se questo comportamento si riproduce anche sul 2013 e sul 2016.