SharePoint | Ejecutándo código después de la carga de los Display Templates

Cuando desarrollamos Display Templates para dar un look&feel diferente a los elementos resultantes de las búsquedas en SharePoint, muchas veces es necesario ejecutar código JavasScript tras la carga de los mismos ya sea para añadir funcionalidad extra o simplemente para establecer algunas propiedades visuales que requieran de conocer los resultados para mostrar una mejor distribución.

Escenario

Supongamos que almacenamos vídeos de youtube en una lista y que queremos mostrar uno de ellos mediante una búsqueda con un Content Search web part (CSWP), usando para ello un iframe en el que incrustaremos la Url (embed) del vídeo que podemos tomar de la opción de compartir –> insertar.

Posteriormente, como el iframe no es un elemento que se adapte a las dimensiones de su contenedor, si queremos que se muestre con el ancho de éste y una altura proporcional, deberemos usar código JavaScript para que sea posible y aplicarle al iframe las dimensiones correctas.

Problema

Como muchos estaréis pensando, podríamos usar un bloque de jQuery que se ejecute cuando termine la carga de la página pero… en SharePoint no nos vale porque se ejecutan procesos posteriores. La otra posibilidad que debéis conocer, ya que estamos en SharePoint y éste nos provee de una pila de scripts que se ejecutan cuando se considera que se ha terminado la carga de la página, deberíamos usar esta pila e incrustar nuestras funciones JavaScript para que se apilen y se ejecuten dentro de ese ámbito… cosa que funciona dentro de layouts, masterpage,… peeeeero, no en los Display Templates. ¿Por qué? pues porque los resultados de la búsqueda se cargan en el DOM de forma dinámica/asíncrona y nada asegura que cuando se haya cargado la página ya se hayan insertado en el DOM los elementos resultantes, de hecho, muy muy rara vez ocurrirá que se inserten antes con lo que habrá que buscar una nueva solución

Solución

Bueno, como a veces se hacen las cosas bien, dentro de los display templates podemos acceder a otra pila de scripts a ejecutar tras la carga pero, esta vez, dentro del ámbito del Content Search Web Part. Para ello, lo primero que tenemos que hacer es incluir el script donde se encuentra nuestro código en la cabecera del display template (yo siempre lo hago en el display template de control) Contro_MyDisplayTemplate


$includeLanguageScript(this.url, "~sitecollection/_catalogs/masterpage/Display Templates/Language Files/{Locale}/CustomStrings.js");
$includeCSS(this.url, "~sitecollection/_layouts/15/Demo/styles/templates/video.min.css");
$includeScript(this.url, "~sitecollection/_layouts/15/Demo/scripts/custom/video.js");


Ahora que ya tenemos acceso a nuestras funciones de JavaScript, debemos añadir un bloque de código en el Display Template (ya sabéis que va con <!–#_ ….. my code … _#—>) con el código que os muestro a continuación. Yo siempre lo añado también en el Display Template de control y al final.

<!--#_
ctx.OnPostRender = [];
ctx.OnPostRender.push(function() {
// My JavaScript code
var video = new Video();
video.Initialize();
// .....
});
_#-->

También podemos hacerlo de esta otra forma obteniendo el mismo resultado sin necesidad de definir nosotros mismos OnPostRender

<!--#_
AddPostRenderCallback(ctx, function(){
var video = new Video();
video.Initialize();
});
_#-->

Una vez hayamos hecho esto, nos habremos asegurado que nuestro código se ejecutará tras la carga de los elementos resultantes de la búsqueda y, en nuestro ejemplo, habremos conseguido que se le asignen las dimensiones correctas al iframe que contiene el vídeo.

Enjoy coding!!