Registrati JS per il tipo di campo personalizzato in SharePoint 2013
-
10-12-2019 - |
Domanda
Ho un tipo di campo personalizzato per SharePoint 2010/2007, ma dopo essere migrato a SharePoint 2013, ho soddisfatto un problema.
Ecco cosa ho definito per "renderpattern" in fldtypes_myfield.xml
<RenderPattern Name="DisplayPattern">
<HTML><![CDATA[<script type="text/javascript" src="/_layouts/myfield/myjs.js"></script>]]></HTML>
<HTML><![CDATA[<img src="/_layouts/images/myfield/pic.png" onload="myfun()">]]></HTML>
</RenderPattern>
.
myfun () è definito in myjs.js, quindi quando viene caricata Pic.png, eseguirà la funzione. Funziona bene nell'esperienza utente 2010/2007 e 2010 in SharePoint 2013.
Nel 2013, nell'esperienza utente del 2013, quando vedo l'elenco che contiene MyField, getta l'errore:
myfun is not defined
.
Quindi, il motivo è ovvio, myjs.js non è aggiunto alla pagina. (Il collegamento JS è corretto, copia il collegamento alla barra degli indirizzi e il browser può visualizzarlo)
Quindi, la mia domanda è: perché myjs.js non è registrato?
Qualche idea? Grazie in anticipo.
Aggiornamento:
Non funziona nella pagina "ListView", ma funziona nella pagina "DisplayForm". "CamlRendering" è impostato su TRUE. Sotto pagina "ListView", se si seleziona il campo con lo strumento per sviluppatori Web, il markup HTML all'interno è:
.
<SCRIPT type=text/javascript src="/_layouts/myfield/myjs.js"></SCRIPT>
<DIV><IMG src="/_layouts/images/myfield/pic.png" onload="myfun()"></DIV>
SharePoint 2013 vieta il carico JS?
Soluzione
Dopo il debug, ho trovato che c'è una variabile chiamata "wpq2listdata" che memorizza il contenuto dei dati dell'elenco, il suo formato è:
var WPQ2ListData = {
"Row": [{
"ID": "1",
"PermMask": "0x7fffffffffffffff",
"FSObjType": "0",
"Title": "A",
"FileLeafRef": "1_.000",
"Created_x0020_Date.ifnew": "1",
"FileRef": "\u002ftest\u002fLists\u002fRatingList\u002f1_.000",
"File_x0020_Type": "",
"File_x0020_Type.mapapp": "",
"HTML_x0020_File_x0020_Type.File_x0020_Type.mapcon": "",
"HTML_x0020_File_x0020_Type.File_x0020_Type.mapico": "icgen.gif",
"ContentTypeId": "0x01008AD43674D321D3428ACAFC1C3BD2971E",
"MyField": "<script type=\"text/javascript\" src=\"/_layouts/myfield/myjs.js\"></script><img src=\"/_layouts/images/myfield/pic.png\" onload=\"myfun()\">"
}],
"FirstRow": 1,
"LastRow": 1,
"FilterLink": "?",
"ForceNoHierarchy": "1",
"HierarchyHasIndention": ""
.
}
Presta attenzione a "Myfield", ha il contenuto che dovrebbe essere reso.
Nella pagina, "WPQ2ListData" è utilizzato in un unico punto:
ctx = new ContextInfo();
//other assignments
ctx.ListData = WPQ2ListData;
.
Quindi "CTX" verrà passato alla funzione "RenderListView", che è responsabile del rendering della visualizzazione dell'elenco. Questa funzione è definita in "clienttemplates.js". Se ti tuffini, scoprirai che chiamerà un'altra funzione chiamata "SPCRIENTRENDERER.RENDER", in questa funzione genererà l'intero contenuto HTML per i dati dell'elenco e inserirlo su un TD (forse un div) come Innerhtml.
var result = SPClientRenderer.RenderCore(renderCtx);
if (result != null && result != '') {
if (node.tagName == "DIV" || node.tagName == "TD") {
if (renderCtx.fHidden)
if (renderCtx.fHidden)
node.innerHTML = result;
}else{
//create div element, and insert result as innerHTML
}
}
.
Presta attenzione a "Node.innerhtml= Risultato", poiché Se alcuni contenuti stringa sono inseriti su un elemento come INNERHTML e il contenuto contiene codice JavaScript, il codice JS non verrà eseguito. Ed è per questo che "myjs.js" non è aggiunto alla pagina! Penso che questa sia una delle grandi differenze sulla vista elenco di rendering nel 2010 e nel 2013, nel 2010, Elenco Data HTML viene emesso direttamente sulla pagina, mentre è inserito alla pagina dinamicamente nel 2013.
Soluzione:
In realtà, c'è ancora un posto che contiene codice JS e può eseguire il codice. È "onload" in IMG. Quindi, perché non registrare il nostro file JS qui? E dopo che myjs.js è caricato, lascia chiamare MyFun ()!
.
var head = document.getElementsByTagName("head")[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = '/_layouts/myfield/myjs.js';
script.onload = script.onreadystatechange = function() {
myfun();
};
head.appendChild(script);
E per prestazioni migliori, non dobbiamo registrare Myjs.js per ogni riga, dovremmo controllare se esiste prima.