sábado, 8 de agosto de 2015

Problemas con los flujos de trabajo en las encuestas en SharePoint 2007

Hoy un cliente que usa MOSS (SharePoint 2007), me ha pedido que cree una encuesta. Hasta aquí ningún problema, encuesta creada con sus maravillosas bifurcaciones.

Los problemas han venido cuando me ha dicho que un usuario podía responder varias veces a la encuesta. Eso no es un problema en sí, el problema viene cuando el usuario a los días se ha dado cuenta de que ha respondido mal a la encuesta. Entonces puede ser un problema saber cual es la respuesta que coincide con la respuesta a modificar.

Lo primero que se me ha ocurrido ha sido, crear o modificar una vista, para mostrar en ella, el campo que diferenciaría cada respuesta, en mi caso el campo "operación", pero que por el alto número de operaciones que tenían, he separado en 9 preguntas de operación que se llega a ella por medio de una bifurcación al elegir el departamento.
Para mi sorpresa en una lista no se puede crear vistas, ni modificar vistas (Si que se puede añadir campos con SharePoint Designer):


Pero no sería solución porque tendría que sacar las 9 columnas de operación.

Las encuestas tampoco aceptan columnas calculadas, en la cual, podría concatenar en una sola columna, la concatenación de las 9 y mostrar dicha columna.

Lo siguiente que se me ha ocurrido es crear un correo, que además de confirmarle al usuario la respuesta en la encuesta, les ponga un enlace a la edición de la respuesta en sí.

Me pongo manos a la obra y cuando esta finalizado, me encuentro con que me aparece la columna del flujo en la vista por defecto, como siempre, pero con este mensaje:


Busco en San Google y encuentro esta maravillosa página de Microsoft:
https://support.microsoft.com/es-es/kb/926370

En la que por si desaparece, os copio lo que pone:

"Considere el siguiente escenario. Cree una encuesta y, a continuación, agregue un flujo de trabajo a la encuesta en Microsoft Windows SharePoint Services 3.0. A continuación, conectarse a la encuesta y responder a él. Por último, ver la respuesta que ha enviado y, a continuación, intenta iniciar un flujo de trabajo de la respuesta. Para ello, haga clic en la flecha situada junto a la respuesta, haga clic en flujos de trabajo, haga clic en el flujo de trabajo que ha agregado, escriba su nombre de usuario en el cuadro de los revisores y, a continuación, haga clic en Inicio. Sin embargo, no se inicia el flujo de trabajo. En su lugar, el estado del flujo de trabajo aparece como Error al iniciar."

Que suerte, justo lo que me pasa a mi, busco la solución y me encuentro:

"Este problema se produce porque a partir de un flujo de trabajo de una respuesta de encuesta no es compatible con Windows SharePoint Services 3.0. Aunque la opción de flujos de trabajo aparece al hacer clic en la flecha situada junto a la respuesta de una encuesta, no se puede iniciar un flujo de trabajo de respuesta de una encuesta."

Perfecto, descubro que las encuestas no soportan los flujos. Por cierto, la traducción rara, ha sido cortesía de Google.

Y las alertas no me sirven, porque no puedo hacer que llegue una alerta al creador y sólo al creador, cuando este crea un elemento:


Conclusión, la encuestas son maravillosas, pero no soportan:

  • Flujos
  • Vistas personalizadas
  • Alertas para indicarme que he respondido a la encuesta
  • Columnas calculadas


domingo, 12 de julio de 2015

¿Qué plantilla de sitio se está usando en mi sitio?

Algunas veces nos puede interesar saber que plantilla de sitio ha sido utilizada para la creación de un sitio en concreto. Pues en SharePoint 2010 y 2013 hay una manera muy sencilla de hacerlo.

Basta con hacer clic con el botón derecho sobre la página del sitio que queremos conocer su plantilla y en el menú contextual que nos sale, elegiremos la opción de Ver código fuente:


Esto nos abrirá una nueva ventana con el código fuente de la página en cuestión. Ahora sólo habrá que buscar g_wsaSiteTemplateId en el código (para ello podremos utilizar el buscador Ctrl+F):



Y ahora copiaremos el identificador de la plantilla, en mi caso, PROJECTSITE#0 e iremos a buscarla a la página de Microsoft:
http://social.technet.microsoft.com/wiki/contents/articles/20100.sharepoint-2010-default-site-templates.aspx
ó
http://social.technet.microsoft.com/wiki/contents/articles/20149.sharepoint-2013-default-site-templates.aspx

De hecho, también hay una página interesante con los cambios que ha habido de la versión 2010 a la 2013:
https://technet.microsoft.com/en-us/library/ff607742.aspx

En nuestro caso, veremos que es una plantilla de sitio de proyectos:


Como podéis ver, ha sido muy fácil.


sábado, 27 de junio de 2015

Error en los espacios de reunión de SharePoint: 'g_InstanceID' no esta definido

Jugando con las páginas maestras en SharePoint, descubrí que al volver a aplicar la default.master, a un sitio que tuviera como subsitio un espacio de reuniones, me genero un error de Javascript que me decía que 'g_InstanceID' no esta definido y me impedía que al hacer clic en las fechas de la parte izquierda, pudiera ver el contenido de los documentos asociados a dicha fecha:


Para solucionar esto, basta con hacer una copia de la página maestra, en nuestro caso default.master, renombrarla y añadir tras la etiqueta <%@ Import Namespace=”Microsoft.SharePoint” %>:


<%@ Register Tagprefix="Meetings" Namespace="Microsoft.SharePoint.Meetings" 
Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, 
PublicKeyToken=71e9bce111e9429c" %>

Y tras la apertura de la etiqueta de <body> añadiremos:

<Meetings:PropertyBag runat="server"/>

Guardaremos la nueva pagina maestra, la publicaremos y la aplicaremos a nuestro espacio de reuniones y veremos como el problema se ha solucionado.

Fuente: http://sympmarc.com/2008/07/02/how-to-fix-recurring-meeting-workspace-error-%E2%80%98g_instanceid%E2%80%99-is-undefined/

sábado, 16 de mayo de 2015

Imagen aleatoria

Hoy un cliente me ha pedido que quería una foto aleatoria en el portal. Diferente para cada vez que accediera al portal.

La solución ha sido fácil.

Primero he creado una Biblioteca de Imágenes. En ella una columna de o No, con valor por defecto a . Que nos servirá para que el propio usuario elija entre que fotos quiere que se haga la selección sin tener que eliminarlas de la biblioteca. Sólo tendrá que marcarlas a No.

Lo siguiente ha consistido en hacer una Vista de Datos, en la que mostramos todos los elementos y filtramos por los que el campo anterior esta a Sí. SharePoint Designer generará todo el código por nosotros. Veremos que tenemos todas las fotos en una tabla, una debajo de otra.

Ahora entraremos en código y buscaremos:

<xsl:template name="dvt_1">
<xsl:variable name="dvt_StyleName">Table</xsl:variable>
<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row"/>

Y añadiremos la siguiente lineas tras lo anterior:

<xsl:variable name="totalRows" select="count($Rows)" />

Quedando:

<xsl:template name="dvt_1">
<xsl:variable name="dvt_StyleName">Table</xsl:variable>
<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row"/> <xsl:variable name="totalRows" select="count($Rows)" />

Lo único que hemos hecho, es recoger en totalRows, el número de imágenes que están marcadas a .
Buscaremos la llamada al Body:

<xsl:call-template name="dvt_1.body">

Y justo antes de él, crearemos nuestro número aleatorio y los guardaremos en una variable:

<xsl:variable name="RandomNumber" select="ddwrt:Random(1, $totalRows)" />

Ya tenemos lo más importante, nuestro número aleatorio, entre 1 y el número de imágenes totales con la columna marcada a . Y se las pasaremos como parámetro a dvt_1.body. Quedando el código:

<xsl:variable name="RandomNumber" select="ddwrt:Random(1, $totalRows)" />
<xsl:call-template name="dvt_1.body">
<xsl:with-param name="Rows" select="$Rows"/>
<xsl:with-param name="RandomNumber" select="$RandomNumber"/>
</xsl:call-template>

Dentro de dvt_1.body recogeremos el valor de RandomNumbre y se lo pasaremos a la función dvt_1.rowview que es la que pinta cada uno de los elementos por medio de un for-each, quedando:

<xsl:template name="dvt_1.body">
<xsl:param name="Rows"/>
<xsl:param name="RandomNumber"/>
<xsl:for-each select="$Rows">
<xsl:call-template name="dvt_1.rowview">
<xsl:with-param name="RandomNumber" select="$RandomNumber"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>

Y por último, dentro de dvt_1.rowview, recogeremos el valor de RandomNumber y por medio de un if, pintaremos sólo el elemento (@ID) que coincida con nuestro número aleatorio. Quedando:

<xsl:template name="dvt_1.rowview">
<xsl:param name="RandomNumber"/>
<xsl:if test="@ID = $RandomNumber">
<tr>
                                <td>
                                     <img border="0" src="{@FileRef}"/>
</td>
                        </tr>
</xsl:if>
</xsl:template>

La maquetación ya corre por cuenta de cada uno. En mi caso, debía ocupar el 100% de la página y tener un borde negro.

Esta vez no he buscado en San Google, sino que como tenía poco trabajo, lo he creado pensando un poquito. Como se puede ver, no ha sido muy complicado, aunque estoy seguro, que si buscáis, habrá mil maneras de hacerlo.


sábado, 25 de abril de 2015

Obtener parámetros de la URL

Constantemente utilizamos la URL para pasar parámetros cuando estamos trabajando con SharePoint. De hecho el propio SharePoint es el primero que lo hace y el caso más fácil de ver, es cuando accedemos a un elemento de lista, ya sea en forma de edición o de presentación:

http://misitoweb/Lists/Alertas/EditForm.aspx?ID=39&Source=http%3A%2F%2Fmisitioweb%2FLists%2FAlertas%2FAllItems%2Easpx

En este ejemplo, podemos ver que tenemos dos parámetros ID y Source, que sirven para identificar el elemento y a dónde nos va a llevar una vez aceptemos o cancelemos la edición del elemento.

Normalmente para obtener y tratarlo, utilizaríamos JavaScript y/o JQuery, y trataríamos la URL.

La idea que propongo en esta entrada es encapsular una función que ya nos lo obtenga y que incluyéndola en un archivo .js, nos permitiría referenciarla en la página maestra y utilizar en nuestro portal.

El código sería sencillo:

function getUrlVars() {
  var vars = {};
  var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
    vars[key] = value;
  });
  return vars;
}


Esto nos permitiría recuperar dicho parámetro haciendo algo tan sencillo como:

var elemento = getUrlVars()["ID"];
var destino = getUrlVars()["Source"];

Y poder trabajar con ellas. Como se ve, es algo fácil y sencillo.

La idea la obtuve de:
http://papermashup.com/read-url-get-variables-withjavascript/

miércoles, 18 de marzo de 2015

Otra manera de abrir en nueva ventana en una vista de datos

Buscando por internet como abrir documentos en otra ventana, encontré una manera curiosa:

<script src="https://ajax.microsoft.com/ajax/jquery/jquery-1.3.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
  $("a[href$='#openinnewwindow']").each(function() {
    $(this).attr("target", "_blank");
    $(this).attr("href", $(this).attr("href").replace(/#openinnewwindow/, ''));
  });
});
</script>


Traducido significa, que en una vista de datos, en una consulta de contenido o en un resultado de búsqueda, todos los enlaces que yo quiera que se abran en nueva ventana, basta con que los marque con id="openinnewwindow" y este código que puede ir en la página maestra, en un archivo js referenciado o directamente en un editor de contenido, hará que busque todos estos elementos, les ponga un target="_blank" y elimine del id el valor openinnewwindow reemplazándolo por ''.

Fácil y sencillo.

 La página donde encontré esta curiosa propuesta es:
http://blog.scoreman.net/2010/10/open-sharepoint-links-in-new-window-using-jquery/

sábado, 21 de febrero de 2015

Abrir PDF's en nueva ventana

En uno de los clientes, me han pedido que los PDF no se abrieran en el navegador.

Esto les supone un problema porque al cerrar el PDF, suelen cerrar el navegador y luego tiene que volver a entrar.

Para resolver este problema, en la configuración avanzada de la biblioteca, existe la posibilidad de abrir los documentos en la aplicación nativa:


Pero en nuestro caso, esto no funciona porque en la configuración del propio Adobe Reader, tienen marcado que se abra en el navegador. Cambiar esto les supone un gran trastorno dentro de la empresa, así que tome la opción de hacerlo vía JQuery:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>

/*Que se ejecute cuando ya se haya cargado toda la página*/
$(document).ready(function(){

     /*Buscamos todos los documentos que acaben en .pdf*/
    $('[href$=".pdf"]').each(function(){ 

        /*Vacio el onclick que suele traer*/    
       $(this).attr('onclick','');

        /*Y le pongo el atributo target="_blank"*/
       $(this).attr('target','_blank');
    });
});
</script>


Incluyendo dicho código en la pagina maestra, ya lo tendríamos disponible para toda la colección de sitios.

Fácil y sencillo. Y el cliente ha quedo contento.