Para aquellos que alguna vez se han enfrentado a la construcción de un sitio de publicación, sabrán lo complicado que es hacer algo “vistoso”, y habrá escuchado de su cliente, en más de una ocasión, la frase: “que soso queda, le falta algo”.
Y que demonios!! levan razón! hacer algo vistoso, no es algo que Sharepoint lleve “out of the box», así que requiere de bastante conocimiento y horas de desarrollo. Afortunadamente, jQuery ha facilitado la tarea, permitiendo que la inserción de “efectos visuales”, sea más sencilla.
Antes de seguir, y por aquello de poner el caramelo en la boca, aquí tenéis una lista de los mejores sites hechos con Sharepoint del 2009:
http://www.topsharepoint.com/top-rated-sharepoint-sites-for-2009
En este post, vamos a ver cómo podemos insertar un efecto jQuery, dentro de Sharepoint. En concreto vamos a usar el “image slide menu”, que podéis ver funcionando en: http://jquerystyle.com/2009/05/07/image-menu-with-jquery
Y lo vamos a complicar un poco, para que las imágenes a mostrar, las saque de una biblioteca de imágenes de Sharepoint, de esta forma, las imágenes pueden cambiarse de forma fácil, sin entrar en código.
Llamada asíncrona al web service de Listas de Sharepoint
Antes de nada, vamos a recuperar el listado de imágenes que queremos incluir en el efecto, y para ello, haremos una llamada asíncrona al web service de Sharepoint, que maneja Listas:
http://Nombre_servidor/sitio/_vti_bin/lists.asmx
Para ello, lo más sencillo, es añadir una nueva página .aspx dentro de una biblioteca de documentos, desde Sharepoint Designer. Editamos el código fuente y añadimos, dentro del ContentPlaceHolder “PlaceHolderAdditionalPageHead”:
1) Los scripts jQuery necesarios.
1 |
<span id="lnum1" style="color: #606060"> 1:</span> <script type=<span style="color: #006080">"text/javascript"</span> src=<span style="color: #006080">"/_layouts/SmartTools.jQuery/jquery.js"</span>></script> |
1 |
<span id="lnum2" style="color: #606060"> 2:</span> <script type=<span style="color: #006080">"text/javascript"</span> src=<span style="color: #006080">"/_layouts/SmartTools.jQuery/jquery-easing-1.3.pack.js"</span>></script> |
1 |
<span id="lnum3" style="color: #606060"> 3:</span> <script type=<span style="color: #006080">"text/javascript"</span> src=<span style="color: #006080">"/_layouts/SmartTools.jQuery/jquery-easing-compatibility.1.2.pack.js"</span>></script> |
1 |
<span id="lnum4" style="color: #606060"> 4:</span> <link rel=<span style="color: #006080">"stylesheet"</span> type=<span style="color: #006080">"text/css"</span> href=<span style="color: #006080">"/_styles/jimgMenu.css"</span>/> |
2) La llamada, se hace usando la función Ajax, de jQuery:
1 |
<span id="lnum1" style="color: #606060"> 1:</span> $.ajax({ |
1 |
<span id="lnum2" style="color: #606060"> 2:</span> url: url del web service, |
1 |
<span id="lnum3" style="color: #606060"> 3:</span> type: <span style="color: #006080">"POST"</span>, |
1 |
<span id="lnum4" style="color: #606060"> 4:</span> dataType: <span style="color: #006080">"xml"</span>, |
1 |
<span id="lnum5" style="color: #606060"> 5:</span> data: soapEnv, |
1 |
<span id="lnum6" style="color: #606060"> 6:</span> complete: processResult, |
1 |
<span id="lnum7" style="color: #606060"> 7:</span> contentType: <span style="color: #006080">"text/xml; charset="</span>utf-8<span style="color: #006080">""</span> |
1 |
<span id="lnum8" style="color: #606060"> 8:</span> }); |
El parámetro “data”, corresponde al xml del SOAP envelope, que le indica, el método del webservice que debe invocar, y los parámetros que le pasa. Si lo que queremos es obtener los elementos de una lista, el soap de entrada, sería:
1 |
<span id="lnum1" style="color: #606060"> 1:</span> <span style="color: #0000ff">var</span> soapEnv = |
1 |
<span id="lnum2" style="color: #606060"> 2:</span> <span style="color: #006080">"<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'> </span> + listName + <span style="color: #006080">"</listName>"</span> + |
1 |
<span id="lnum3" style="color: #606060"> 3:</span> <soapenv:Body> |
1 |
<span id="lnum4" style="color: #606060"> 4:</span> <GetListItems xmlns='http://schemas.microsoft.com/sharepoint/soap/'> |
1 |
<span id="lnum5" style="color: #606060"> 5:</span> <listName>" |
1 |
<span id="lnum6" style="color: #606060"> 6:</span> <span style="color: #006080">"</GetListItems> </span>; |
1 |
<span id="lnum7" style="color: #606060"> 7:</span> </soapenv:Body> |
1 |
<span id="lnum8" style="color: #606060"> 8:</span> </soapenv:Envelope>" |
El parámetro “complete”, indica la función que se ejecutará de retorno de la llamada asíncrona.
Procesando resultado de la llamada asíncrona
Una vez finalizada la llamada asíncrona al web service, procesamos el mensaje SOAP devuelto.
[TIP]: Como truquillo, tanto para sacar el mensaje SOAP de llamada a una función del webservice (SOAP request), como para ver el resultado de esa función (SOAP response), os recomiendo que os creéis un sencillo cliente con Visual Studio (una app de consola, por ejemplo), agreguéis la referencia al web service que queréis usar, y utilicéis el proxy que te genera el VS para invocar al web method que queráis, (así tendréis el intellisense y el tipado de datos). A esto, le añadimos el uso del Fiddler, que nos sacará las tripas de la llamada al web service, y su resultado. Fijaros en la imagen:
A mano derecha, aparecen todas las llamadas que se han hecho al servidor en la petición (varias imágenes, hojas de estilos, etc). Una de esas llamadas es las del webservice (lists.asmx). Si la seleccionamos, en la zona superior izquierda, podemos ver la información de la petición. Si ponemos la vista de XML, podemos ver el SOAP request, y si hacemos lo mismo en la zona inferior, veremos la respuesta del servidor. Si ponemos la vista “TextView”, podemos copiar y pegar el SOAP, para luego meterlo dentro de nuestra página de Sharepoint.
Una vez tenemos claro, cuál es el mensaje de respuesta a nuestra llamada, se trata de parsear con jQuery, el XML resultante.
Antes de eso, vamos a meter un DIV en nuestra página, que será el contenedor del HTML que compondremos desde jQuery. Lo insertamos dentro dentro del ContentPlaceHolder “PlaceHolderMain”:
1 |
<span id="lnum1" style="color: #606060"> 1:</span> <span style="color: #0000ff"><</span><span style="color: #800000">div</span> <span style="color: #ff0000">class</span><span style="color: #0000ff">="jimgMenu"</span><span style="color: #0000ff">></span> |
1 |
<span id="lnum2" style="color: #606060"> 2:</span> <span style="color: #0000ff"><</span><span style="color: #800000">ul</span><span style="color: #0000ff">></span> |
1 |
<span id="lnum3" style="color: #606060"> 3:</span> <span style="color: #0000ff"></</span><span style="color: #800000">ul</span><span style="color: #0000ff">></span> |
1 |
<span id="lnum4" style="color: #606060"> 4:</span> <span style="color: #0000ff"></</span><span style="color: #800000">div</span><span style="color: #0000ff">></span> |
Ahora ya podemos inyectar el HTML. Para ello
- Recorremos todos los nodos del XML, que corresponden a los items de la lista (las imágenes que queremos mostrar).
- Sacamos la URL de la imagen
- Montamos los elementos <li> necesarios, con los estilos necesario, para que los scripts de jQuery, hagan el efecto visual.
El código sería algo como:
1 |
<span id="lnum1" style="color: #606060"> 1:</span> <span style="color: #008000">//recorremos cada nodo de la lista de items</span> |
1 |
<span id="lnum2" style="color: #606060"> 2:</span> Data.responseXML).find(<span style="color: #006080">"z\:row"</span>).each(<span style="color: #0000ff">function</span>() { |
1 |
<span id="lnum3" style="color: #606060"> 3:</span> |
1 |
<span id="lnum4" style="color: #606060"> 4:</span> <span style="color: #008000">//el estilo de cada item, se creará dinámico: imgMenu1, imgMenu2...</span> |
1 |
<span id="lnum5" style="color: #606060"> 5:</span> <span style="color: #0000ff">var</span> style_li = <span style="color: #006080">"imgMenu"</span> + counter; |
1 |
<span id="lnum6" style="color: #606060"> 6:</span> <span style="color: #008000">//obtenemos el titulo de la imagen</span> |
1 |
<span id="lnum7" style="color: #606060"> 7:</span> <span style="color: #0000ff">var</span> texto = $(<span style="color: #0000ff">this</span>).attr(attrName); |
1 |
<span id="lnum8" style="color: #606060"> 8:</span> <span style="color: #008000">//obtenemos el path de la imagen</span> |
1 |
<span id="lnum9" style="color: #606060"> 9:</span> <span style="color: #0000ff">var</span> imgPath = $(<span style="color: #0000ff">this</span>).attr(<span style="color: #006080">"ows_RequiredField"</span>); |
1 |
<span id="lnum10" style="color: #606060"> 10:</span> |
1 |
<span id="lnum11" style="color: #606060"> 11:</span> <span style="color: #008000">//la imagen, se carga desde el estilo, pero se monta un LI por cada imagen</span> |
1 |
<span id="lnum12" style="color: #606060"> 12:</span> <span style="color: #008000">//asignandole el estilo de forma dinamica</span> |
1 |
<span id="lnum13" style="color: #606060"> 13:</span> <span style="color: #0000ff">var</span> liImg = <span style="color: #006080">"<li class='"</span> + style_li + <span style="color: #006080">"'><a href='#'>"</span> + texto + <span style="color: #006080">"</a></li>"</span> ; |
1 |
<span id="lnum14" style="color: #606060"> 14:</span> <span style="color: #008000">//inyectamos el html al DIV contenedor</span> |
1 |
<span id="lnum15" style="color: #606060"> 15:</span> $(<span style="color: #006080">".jimgMenu ul"</span>).append(liImg); |
1 |
<span id="lnum16" style="color: #606060"> 16:</span> |
1 |
<span id="lnum17" style="color: #606060"> 17:</span> <span style="color: #008000">//generamos el estilo de forma dinamica, poniendo como background, </span> |
1 |
<span id="lnum18" style="color: #606060"> 18:</span> <span style="color: #008000">//la imagen deseada de la lista</span> |
1 |
<span id="lnum19" style="color: #606060"> 19:</span> <span style="color: #0000ff">var</span> selectorStyleItem = <span style="color: #006080">".jimgMenu ul li."</span> + style_li + <span style="color: #006080">" a"</span>; |
1 |
<span id="lnum20" style="color: #606060"> 20:</span> <span style="color: #0000ff">var</span> bg = <span style="color: #006080">"url(/"</span> + imgPath + <span style="color: #006080">") repeat scroll 0%"</span>; |
1 |
<span id="lnum21" style="color: #606060"> 21:</span> $(selectorStyleItem).css(<span style="color: #006080">"background"</span>, bg); |
1 |
<span id="lnum22" style="color: #606060"> 22:</span> |
1 |
<span id="lnum23" style="color: #606060"> 23:</span> counter++; |
1 |
<span id="lnum24" style="color: #606060"> 24:</span> }); |
Añadiendo efectos visuales con jQuery
Hasta ahora, lo único que hemos hecho es montar el HTML del efecto, con los estilos necesarios, y sacando las imágenes de forma dinámica. Ahora nos falta añadir el jQuery necesario para los efectos de “slide” de las imágenes.
Para ello, utilizamos el siguiente código, dentro de la misma función retorno de la llamada asíncrona (justo después del código anterior):
1 |
<span id="lnum1" style="color: #606060"> 1:</span> $(<span style="color: #006080">'div.jimgMenu ul li a'</span>).hover(<span style="color: #0000ff">function</span>() { |
1 |
<span id="lnum2" style="color: #606060"> 2:</span> <span style="color: #0000ff">if</span> ($(<span style="color: #0000ff">this</span>).<span style="color: #0000ff">is</span>(<span style="color: #006080">':animated'</span>)) { |
1 |
<span id="lnum3" style="color: #606060"> 3:</span> $(<span style="color: #0000ff">this</span>).stop().animate({width: <span style="color: #006080">"310px"</span>}, {duration: 450, easing:<span style="color: #006080">"easeOutQuad"</span>, complete: <span style="color: #006080">"callback"</span>}); |
1 |
<span id="lnum4" style="color: #606060"> 4:</span> } <span style="color: #0000ff">else</span> { |
1 |
<span id="lnum5" style="color: #606060"> 5:</span> <span style="color: #008000">// ease in quickly</span> |
1 |
<span id="lnum6" style="color: #606060"> 6:</span> $(<span style="color: #0000ff">this</span>).stop().animate({width: <span style="color: #006080">"310px"</span>}, {duration: 400, easing:<span style="color: #006080">"easeOutQuad"</span>, complete: <span style="color: #006080">"callback"</span>}); |
1 |
<span id="lnum7" style="color: #606060"> 7:</span> } |
1 |
<span id="lnum8" style="color: #606060"> 8:</span> }, <span style="color: #0000ff">function</span> () { |
1 |
<span id="lnum9" style="color: #606060"> 9:</span> <span style="color: #008000">// on hovering out, ease the element out</span> |
1 |
<span id="lnum10" style="color: #606060"> 10:</span> <span style="color: #0000ff">if</span> ($(<span style="color: #0000ff">this</span>).<span style="color: #0000ff">is</span>(<span style="color: #006080">':animated'</span>)) { |
1 |
<span id="lnum11" style="color: #606060"> 11:</span> $(<span style="color: #0000ff">this</span>).stop().animate({width: <span style="color: #006080">"78px"</span>}, {duration: 400, easing:<span style="color: #006080">"easeInOutQuad"</span>, complete: <span style="color: #006080">"callback"</span>}) |
1 |
<span id="lnum12" style="color: #606060"> 12:</span> } <span style="color: #0000ff">else</span> { |
1 |
<span id="lnum13" style="color: #606060"> 13:</span> <span style="color: #008000">// ease out slowly</span> |
1 |
<span id="lnum14" style="color: #606060"> 14:</span> $(<span style="color: #0000ff">this</span>).stop(<span style="color: #006080">':animated'</span>).animate({width: <span style="color: #006080">"78px"</span>}, {duration: 450, easing:<span style="color: #006080">"easeInOutQuad"</span>, complete: <span style="color: #006080">"callback"</span>}); |
1 |
<span id="lnum15" style="color: #606060"> 15:</span> } |
1 |
<span id="lnum16" style="color: #606060"> 16:</span> }); |
El resultado final !!
Y así queda el efecto, dentro de nuestra página de Sharepoint:
y si editamos la lista de imágenes y añadimos una nueva, automáticamente nos aparece en el menú:
Algunas consideraciones y posibles mejoras
- Este ejemplo está adaptado a las imágenes utilizadas. Si quieres usar otro tamaño de imágenes, tendrás que jugar con los estilos de la CSS y el jQuery, para adaptarlo.
- A pesar que el ejemplo está hecho para cargar las imágenes de una biblioteca, hay que aclarar que no tiene mucho sentido colocar muchas imágenes, ya que no cabrán en el div principal “.jimgMenu”. Digamos que este efecto está pensado para el típico “menú destacado” que aparece en la parte superior de la Home (por debajo de la cabecera).
- En el ejemplo no lo hemos hecho, pero se podría mejorar, si el link al que redirige la imagen, se toma de una columna de la lista.
Nada más, espero que os sea de utilidad. Ya me contareis.
Saludos!!!
Deja un comentario