Modificare la visualizzazione di una lista SharePoint tramite JS Link
JS Link (Client Side Rendering) e la tecnologia che può essere usata in SharePoint 2013 e SharePoint Online per modificare il rendering di una lista (classic), lato client (il browser) tramite JavaScript.
Avevo già mostrato un esempio per modificare solo il rendering di un campo, ma è possibile andare oltre e modificare completamente l'aspetto di una lista.
Il modello oggetti lato client è il seguente:
questo oggetto contiene gli eventi che si possono sovrascrivere per modificare il render di ogni singola parte che compone la visualizzazione di una lista. Gli eventi sono:
Ci sono anche degli eventi generali quali OnPreRender invocato prima di renderizzare qualsiasi elemento e OnPostRender invocato quando il DOM è stato creato (quindi si può accedere agli elementi della lista, ad esempio tramite jquery).
A questi si aggiungono delle proprietà che permetto di "agganciare" gli eventi ad una specifica lista:
Ad esempio per cambiare il render dell'intestazione (header) di una lista:si sovrascrive l'evento Header dell'oggetto Templates:
e questo è il risultato:oppure con una funzione JavaScript:
in questo caso ho mantenuto anche l'header originale tramite la funzione RenderHeaderTemplate:Il codice JavaScript può essere inserito all'interno della pagina tramite una Script Editor Web Part oppure salvato in una document library (es. Style Library) e linkato alla Web Part della lista tramite la proprietà Collegamento JS:
Un altro esempio è quello di modificare completamente il rendering del body della web part mantenendo la paginazione (Footer);
questo esempio si basa su alcune funzioni comuni:
il risultato simile a questo:
Vedi anche SharePoint 2013 : An Introduction to JSLink è Client-side rendering (JS Link) code samples
Avevo già mostrato un esempio per modificare solo il rendering di un campo, ma è possibile andare oltre e modificare completamente l'aspetto di una lista.
Il modello oggetti lato client è il seguente:
JavaScript
var options = {
Templates: {
View: ..., // function or string
Body: ..., // function or string
Header: ..., // function or string
Footer: ..., // function or string
Group: ..., // function or string
Item: ..., // function or string
Fields: {
'Field1 Internal Name': {
View: ..., // function or string
EditForm: ..., // function or string
DisplayForm: ..., // function or string
NewForm: ..., // function or string
},
'Field1 Internal Name': {
View: ..., // function or string
EditForm: ..., // function or string
DisplayForm: ..., // function or string
NewForm: ..., // function or string
},
// .... altri campi
}
},
OnPreRender: ..., // function or array of functions
OnPostRender: ..., // function or array of functions
ListTemplateType: ..., // ID of the list template.
ViewStyle: ..., // ID of the view style
BaseViewID: ..., // BaseViewID of the list view.
};
- Templates.View: sovrascrive completamente tutto il render della lista
- Templates.Body: sovrascrive il body della lista
- Templates.Header: sovrascrive l'header della lista
- Templates.Footer: sovrascrive il footer della lista
- Templates.Group: sovrascrive l'intestazione del raggruppamento degli item della lista
- Templates.Footer: sovrascrive l'item della lista
- Templates.Fields: array che definisce come sovrascrivere lo specifico campo (SharePoint 2013 JSLink per cambiare la modalità con cui vengono visualizzati i campi)
Ci sono anche degli eventi generali quali OnPreRender invocato prima di renderizzare qualsiasi elemento e OnPostRender invocato quando il DOM è stato creato (quindi si può accedere agli elementi della lista, ad esempio tramite jquery).
A questi si aggiungono delle proprietà che permetto di "agganciare" gli eventi ad una specifica lista:
- ListTemplateType: l'id del template di lista
- ViewStyle: l'id del template del tipo di visualizzazione della lista
- BaseViewID: l'id del template di base della lista
Ad esempio per cambiare il render dell'intestazione (header) di una lista:si sovrascrive l'evento Header dell'oggetto Templates:
JavaScript
(function () {
if (typeof SPClientTemplates === "undefined") return;
var options = {};
options.Templates = {};
options.Templates.Header = "<h2>Titolo lista: <#= ctx.ListTitle #></h2>";
SP.SOD.executeFunc("clienttemplates.js", "SPClientTemplates", function () {
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(options);
});
})();
JavaScript
(function () {
if (typeof SPClientTemplates === "undefined") return;
function renderIHeader(ctx) {
return "<h1>Nuovo titolo</h1>" + RenderHeaderTemplate(ctx);
}
var options = {};
options.Templates = {};
options.Templates.Header = renderIHeader;
SP.SOD.executeFunc("clienttemplates.js", "SPClientTemplates", function () {
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(options);
});
})();
Un altro esempio è quello di modificare completamente il rendering del body della web part mantenendo la paginazione (Footer);
JavaScript
(function () {
if (typeof SPClientTemplates === "undefined") return;
function renderBody(ctx) {
var s = "<div class=\"sgart-news\">";
var data = ctx.ListData.Row; // le righe correnti della vista
for (var i = 0; i < data.length; i++) {
var item = data[i];
var classCheckedOut = item.CheckedOutUserId != 0 ? " unpublished" : "";
var imgSrc = sgart.getImageSrc(item.PublishingRollupImage, item.PublishingPageImage);
var dateStr = sgart.formatDateString(item.ArticleStartDate, true);
s += String.format('<div class="row article{5}">'
+ '<div class="col-md-4 col-sx-12">'
+ ' <div class="bw"><a href="{0}"><img class="img-responsive" alt="" src="{1}?RenditionID=5"></a></div>'
+ '</div>'
+ '<div class="col-md-8 col-sx-12">'
+ ' <div class="date">{2}</div>'
+ ' <div class="title"><a title="" href={0}">{3}</a></div>'
+ ' <div class="description">{4}</div>'
+ '</div></div>', item.FileRef, imgSrc, dateStr, item.Title, item.Comments, classCheckedOut);
}
s += '</div>';
return s;
};
var options = {};
options.Templates = {};
options.Templates.Header = " "; // se voglio nascondere l'header non posso lasciare una stringa vuota o un valore null
options.Templates.Body = renderBody; // sovrascrivo il body
SP.SOD.executeFunc("clienttemplates.js", "SPClientTemplates", function () {
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(options);
});
})();
JavaScript
var sgart= sgart|| {};
sgart.mesi = ['', 'Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giungo', 'Luglio', 'Agosto', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre'];
sgart.mesiShort = ['', 'Gen', 'Feb', 'Mar', 'Apr', 'Mag', 'Giu', 'Lug', 'Ago', 'Set', 'Ott', 'Nov', 'Dic'];
sgart.getImageSrc = function (rollupImage, pageImage) { // se non c'è la rollup (rollupImage) ritorno l'immagine principale (pageImage)
var reSrc = /src=\"(.+?)\"/gi;
var str = rollupImage; //"<div dir=\"\" class=\"ms-rtestate-field\"></div>"
var imgSrc = null;
if (typeof str !== "undefined" && str !== null) {
var re = str.match(reSrc);
if (re !== null && re.length > 0)
imgSrc = re[0];
}
if (imgSrc === null) {
var str = pageImage //"<div dir="" class="ms-rtestate-field"><img alt="" src="/News/PublishingImages/nomefile.JPG" style="BORDER:0px solid;" /></div>"
if (typeof str !== "undefined" && str !== null) {
var re = str.match(reSrc);
if (re !== null && re.length > 0)
imgSrc = re[0];
}
}
if (imgSrc !== null) {
imgSrc = imgSrc.substring(5);
var i = imgSrc.indexOf("?");
if (i !== -1)
imgSrc = imgSrc.substring(0, i);
}
return imgSrc;
};
sgart.formatDateString = function (str, toLower) { //input: 16/03/2017
if (str === null || str === "") return "";
var d = str.substr(0, 2);
var m = parseInt(str.substr(3, 2));
var y = str.substr(6, 4);
var mese = sgart.mesiShort[m];
if (typeof toLower === "boolean" && toLower === true)
return d + " " + mese.toLowerCase() + " " + y;
else
return d + " " + mese + " " + y;
};
Attenzione perchè l'esempio riportato funzioni è necessario che la vista contenga i campi utilizzati come: Title, PublishingRollupImage, PublishingPageImage, ecc..
Utilizzare sempre la funzione SP.SOD.executeFunc per registrare gli script in modo da essere sicuri che la libreria clienttemplates.js sia caricata
Con questo script è possibile vedere in console del browser (F12) la sequenza con cui vengono richiamati i singoli eventi:JavaScript
(function () {
if (typeof SPClientTemplates === "undefined") return;
function log(title, ctx){
console.log(title);
//console.log(ctx);
}
function renderView(ctx){
log("View",ctx);
return RenderListView(ctx);
}
function renderBody(ctx){
log("Body rows: " + ctx.ListData.Row.length, ctx);
return RenderBodyTemplate(ctx);
}
function renderHeader(ctx){
log("Header ListTitle: " + ctx.ListTitle, ctx);
log(" - ListTemplateType: " + ctx.ListTemplateType, ctx);
//log(" - ViewStyle: " + ctx.ViewStyle, ctx);
log(" - BaseViewID: " + ctx.BaseViewID, ctx);
return RenderHeaderTemplate(ctx);
}
function renderFooter(ctx){
log("Footer first row: " + ctx.ListData.FirstRow, ctx);
return RenderFooterTemplate(ctx);
}
function renderGroup(ctx){
log("Group id: " + ctx.CurrentItem.ID, ctx);
return RenderGroupTemplate(ctx);
}
function renderItem(ctx){
log("Item id: " + ctx.CurrentItem.ID, ctx);
return RenderItemTemplate(ctx);
}
function renderItem(ctx){
log("Item id: " + ctx.CurrentItem.ID, ctx);
return RenderItemTemplate(ctx);
}
function onPreRender(ctx){
log("OnPreRender", ctx);
//ctx.ListTitle = prompt('Inserisci il titolo della lista', ctx.ListTitle);
//log("OnPreRender new title: " + ctx.ListTitle, ctx);
}
function onPostRender(ctx){
log("OnPostRender", ctx);
}
var options = {};
options.Templates = {};
//options.Templates.View = renderView;
options.Templates.Body = renderBody;
options.Templates.Header = renderHeader;
options.Templates.Footer = renderFooter;
options.Templates.Group = renderGroup;
options.Templates.Item = renderItem;
options.OnPreRender = onPreRender;
options.OnPostRender = onPostRender;
SP.SOD.executeFunc("clienttemplates.js", "SPClientTemplates", function () {
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(options);
});
})();
Text
OnPreRender
Header ListTitle: Pagine
- ListTemplateType: 850
- BaseViewID: 1
Body rows: 3
Item id: 3
Item id: 36
Item id: 7
Footer first row: 1
OnPostRender
Vedi anche SharePoint 2013 : An Introduction to JSLink è Client-side rendering (JS Link) code samples