Mostrando entradas con la etiqueta Javascript. Mostrar todas las entradas
Mostrando entradas con la etiqueta Javascript. Mostrar todas las entradas

domingo, 1 de febrero de 2015

Simple Tip: exportar una vista de una librería con Javascript

A veces nos piden agregar un simple botón para exportar una librería o lista a excel, ya que el que aparece en la ribbon es dificil de encontrar por los usuarios que no conocen mucho la plataforma.

La manera más simple para saber cual es la url que genera un request de exportación a excel, es utilizando la herramienta de networking de Internet Explorer.

Ingreso a la librería, presiono F12 para que aparezcan las herramientas del desarrollador, presiono Play y después presiono el botón de exportar.

image

Hago click derecho sobre la URL, y presiono Copy URL

Abro una nueva ventana,copio la url y verifico que ande bien

Después podemos incrustarla en cualquier parte (botón, javascript, etc)

Ej:

image

jueves, 1 de enero de 2015

Popups (SP.UI.ModalDialog.showModalDialog) en una página WIKI en Sharepoint 2013

Creo una página Wiki

image

Inserto un Script Editor (Embed Code)

image

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<script language="javascript">
 
  function openBasicDialog(tUrl, tTitle) {
         var options = {
             url: tUrl,
             title: tTitle
         };
         SP.UI.ModalDialog.showModalDialog(options);
     }
    
</script>
</head>
<body>
<input type="button" value="Página de Microsoft" onclick="openBasicDialog('http://www.microsoft.com','Microsoft Page');"/>
</body>
</html>

image

Al hacer click en el botón, me lanza un PopUp modal

image

Este script también nos permite mostrar el formulario de NewItems para Listas o el formulario de Upload para Librerias.

Por ej: si utilizo la url de upload de una Librería con el parámetro IsDlg, el cual permite mostrar un form preparado para PopUp (sin barras de desplazamiento, tamaño más reducido, etc). Por ejemplo la siguiente URL

http://URLSite/_layouts/15/Upload.aspx?List={ID_Lista}&RootFolder=&IsDlg=1

image

Entonces lo único que debo hacer es cambiar en el button, la url

<input type="button" value="Agregar Nuevo Documento" onclick="openBasicDialog('http://URLSite/_layouts/15/Upload.aspx?List={ID_Lista}&RootFolder=&IsDlg=1','Librería de Documentos');"/>

Lo cual resulta en

image

image

domingo, 14 de septiembre de 2014

Cómo definir correctamente nuestros archivos de CSR (Client Side Rendering) o jslink

Un problema que suele pasar con jslink es cuando tenemos una página con dos o más webparts que cada uno tiene asignado un archivo jslink. Puede pasar que creamos nuestras funciones de override de campos/header/footer/grouping/etc con nombres iguales en cada archivo jslink.

Ej:

En el web part 1 llama al archivo documentosCSR.js

En el web part 2 llama al archivo taskCSR.js

Ambos archivos tienen un override de la view del campo “Title” y ambos archivos usan la función titleFieldOverride(ctx).

(function() {
    var overrideCtx = {};
    overrideCtx.Templates = {};
    
    overrideCtx.Templates.Fields = {
        'Title': {'View': titleFieldOverride }
    };
    
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
})();

function titleFieldOverride(ctx)
{

}

Que pasa en estos casos? El último archivo js que se cargue será el que prevalece, lo cual puede ocasionar errores dificiles de detectar.

Para ello, siempre crea los archivos jslink con funciones definidas en global namespaces de javascript. Los namespaces nos permiten definir variables, funciones dentro de un “contenedor” ( a efectos prácticos es un objeto ), la idea de trasfondo consiste en que cada archivo jslink utilice su propio namespace para que de esta forma no perdamos funcionalidad al “solapar” el código.

Veamos un ejemplo correcto.

En el archivo documentosCSR.js defino el código de la siguiente manera

var solutionDocumentosCSR = solutionDocumentosCSR || {};
solutionDocumentosCSR.Fields = (function () {
    
    function convertirFecha(fecha) {
        /* convierto la fecha al formato ddMMYYY */
    };
 
    return {
        titleFieldOverride: function (ctx) {
            var html = "<div><strong>" + ctx.CurrentItem.Title + "</strong></div>";
           //aca puedo usar la funcion convertirFecha la cual esta definida dentro del mismo namespace
            return html;
        }
    }
})();

(function() {
    var overrideCtx = {};
    overrideCtx.Templates = {};
    
    overrideCtx.Templates.Fields = {
        'Title': {'View': solutionDocumentosCSR.Fields.titleFieldOverride }
    };
    
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
})();

En el otro archivo  taskCSR.js defino el código de la siguiente manera

var solutionTasksCSR = solutionTasksCSR || {};
solutionTasksCSR.Fields = (function () {
    
    function convertirFecha(fecha) {
        /* convierto la fecha al formato mmDDyyyy */
    };
 
    return {
        titleFieldOverride: function (ctx) {
            var html = "<div><strong>" + ctx.CurrentItem.Title + "</strong></div>";
            //aca puedo usar la funcion convertirFecha la cual esta definida dentro del mismo namespace, y no se toma en cuenta la función definida en el otro namespace
            return html;
        }
    }
})();

(function() {
    var overrideCtx = {};
    overrideCtx.Templates = {};
    
    overrideCtx.Templates.Fields = {
        'Title': {'View': solutionTasksCSR.Fields.titleFieldOverride }
    };
    
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
})();

sábado, 13 de septiembre de 2014

Paginado mediante jslink en Sharepoint 2013 (Paging jslink)

En este ejemplo lo que voy a mostrar es cómo realizar un paginado mediante jslink.

Current enviroment:

  • Enabled Minimal Download Strategy
  • Sharepoint 2013 - 15.0.4551.1511

Tengo la siguiente lista de items y lo que voy a hacer es paginar cada 5 items

image

Creo una página, agrego el web part de la lista y limito la cantidad de items que puedo mostrar.

image

Lo que genera la siguiente vista.

image

Pero que pasa si agregamos código jslink al web part? Por ejemplo el siguiente jslink (no genera override de ninguna funcionalidad)

(function () {

    var itemCtx = {};
    itemCtx.Templates = {};
    itemCtx.BaseViewID = 1;
    itemCtx.ListTemplateType = 100;   
   
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(itemCtx);

})();

lo subo a http://urldelsite/_catalogs/masterpage/ con el contenttype Javascript Display Template

image

En el web part que había agregado anteriormente, le seteo el archivo jslink.

~sitecollection/_catalogs/masterpage/csrpagging.js

Presten atención al tilde (~)

image`

Vemos que sigue funcionando el pagging.

image

Que pasa si agregamos el siguiente código.

(function () {

    var itemCtx = {};
    itemCtx.Templates = {};

    itemCtx.Templates.Header = "<table>";
   
    itemCtx.BaseViewID = 1;
    itemCtx.ListTemplateType = 100;   
   itemCtx.Templates.Footer = "</table>"

    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(itemCtx);

})();

Como se ve en la siguiente imagen, ya no aparece el header ni el footer del web part.

image

Entonces cómo hacemos para agregar el paginado mediante jslink y darle más funcionalidad al footer.


(function () {

    var itemCtx = {};
    itemCtx.Templates = {};

    itemCtx.Templates.Header = "<table>";
   
    itemCtx.BaseViewID = 1;
    itemCtx.ListTemplateType = 100;   
    itemCtx.Templates.Footer = pagingControl;

    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(itemCtx);

})();

function pagingControl(ctx)
{       
        var footerHtml = '<table class="ms-bottompaging"><tr><td>';
        var next = ctx.ListData.NextHref;  
        var prev = ctx.ListData.PrevHref;
  
        if ((next != undefined) && (prev != undefined ))
        {
            footerHtml += "<a class='ms-commandLink ms-promlink-button ms-promlink-button-enabled' href='javascript:void(0);' onclick=\"RefreshPageTo(event, &quot;" + prev + "&quot;);return false;\"><span class='ms-promlink-button-image'><img class='ms-promlink-button-left' src='/_layouts/15/images/spcommon.png?rev=23'/></span></a>";
            footerHtml += "<a class='ms-commandLink ms-promlink-button ms-promlink-button-enabled' href='javascript:void(0);' onclick=\"RefreshPageTo(event, &quot;" + next + "&quot;);return false;\"><span class='ms-promlink-button-image'><img class='ms-promlink-button-right' src='/_layouts/15/images/spcommon.png?rev=23'/></span></a>";
            footerHtml += "</td></tr></table>";           
            footerHtml += "<HR style='margin-left:-20px' COLOR='green' WIDTH='106%'>";
            return footerHtml;       
        }
        else
        {
            if (next != undefined)
            {
                footerHtml += "<a class='ms-commandLink ms-promlink-button ms-promlink-button-enabled' href='javascript:void(0);' onclick=\"RefreshPageTo(event, &quot;" + next + "&quot;);return false;\"><span class='ms-promlink-button-image'><img class='ms-promlink-button-right' src='/_layouts/15/images/spcommon.png?rev=23'/></span></a>";
                footerHtml += "</td></tr></table>";
                footerHtml += "<HR style='margin-left:-20px' COLOR='green' WIDTH='106%'>";
                return footerHtml;       

            }
            else
            {
                if (prev != undefined)
                {
                    footerHtml += "<a class='ms-commandLink ms-promlink-button ms-promlink-button-enabled' href='javascript:void(0);' onclick=\"RefreshPageTo(event, &quot;" + prev + "&quot;);return false;\"><span class='ms-promlink-button-image'><img class='ms-promlink-button-left' src='/_layouts/15/images/spcommon.png?rev=23'/></span></a>";
                    footerHtml += "</td></tr></table>";
                    footerHtml += "<HR style='margin-left:-20px' COLOR='green' WIDTH='106%'>";
                    return footerHtml;       
                }
                else
                    return "<HR style='margin-left:-20px' COLOR='green' WIDTH='106%'>";
            }       
        }
       
}

image image

image

image

En el caso que quisieramos agregar la información de la cantidad de items, podriamos reemplazar la función pagingControl por la siguiente.


function pagingControl(ctx)
{      
       var firstRow = ctx.ListData.FirstRow;
        var lastRow  = ctx.ListData.LastRow;
        var footerHtml = '<table class="ms-bottompaging"><tr><td>';
        var next = ctx.ListData.NextHref;  
        var prev = ctx.ListData.PrevHref;
  
        if ((next != undefined) && (prev != undefined ))
        {
            footerHtml += "<a class='ms-commandLink ms-promlink-button ms-promlink-button-enabled' href='javascript:void(0);' onclick=\"RefreshPageTo(event, &quot;" + prev + "&quot;);return false;\"><span class='ms-promlink-button-image'><img class='ms-promlink-button-left' src='/_layouts/15/images/spcommon.png?rev=23'/></span></a>";
            footerHtml += "<a class='ms-commandLink ms-promlink-button ms-promlink-button-enabled' href='javascript:void(0);' onclick=\"RefreshPageTo(event, &quot;" + next + "&quot;);return false;\"><span class='ms-promlink-button-image'><img class='ms-promlink-button-right' src='/_layouts/15/images/spcommon.png?rev=23'/></span></a>&nbsp" + firstRow  + " de " +  lastRow;
            footerHtml += "</td></tr></table>";           
            footerHtml += "<HR style='margin-left:-20px' COLOR='green' WIDTH='106%'>";
            return footerHtml;       
        }
        else
        {
            if (next != undefined)
            {
                footerHtml += "<a class='ms-commandLink ms-promlink-button ms-promlink-button-enabled' href='javascript:void(0);' onclick=\"RefreshPageTo(event, &quot;" + next + "&quot;);return false;\"><span class='ms-promlink-button-image'><img class='ms-promlink-button-right' src='/_layouts/15/images/spcommon.png?rev=23'/></span></a>&nbsp" + firstRow  + " de " +  lastRow;
                footerHtml += "</td></tr></table>";
                footerHtml += "<HR style='margin-left:-20px' COLOR='green' WIDTH='106%'>";
                return footerHtml;       

            }
            else
            {
                if (prev != undefined)
                {
                    footerHtml += "<a class='ms-commandLink ms-promlink-button ms-promlink-button-enabled' href='javascript:void(0);' onclick=\"RefreshPageTo(event, &quot;" + prev + "&quot;);return false;\"><span class='ms-promlink-button-image'><img class='ms-promlink-button-left' src='/_layouts/15/images/spcommon.png?rev=23'/></span></a>&nbsp" + firstRow  + " de " +  lastRow;
                    footerHtml += "</td></tr></table>";
                    footerHtml += "<HR style='margin-left:-20px' COLOR='green' WIDTH='106%'>";
                    return footerHtml;       
                }
                else
                    return "<HR style='margin-left:-20px' COLOR='green' WIDTH='106%'>";
            }       
        }
       
}

Lo cual permite mostrar la cantidad de items que se ve en la vista (Ej: 6 de 10)

image

Cómo pueden ver en el código se hace uso de una función llamada RefreshPageTo, que está definida en el archivo INPLVIEW.js,

Ingreso al archivo debug, así es más fácil para ver la función

/_layouts/15/inplview.debug.js

image

Les dejo el código js en el siguiente link: http://1drv.ms/1wjDBN5

Podrán encontrar más post sobre jslink en el siguiente tag: http://todosharepoint.blogspot.com.ar/search/label/JSLink

sábado, 30 de agosto de 2014

Variable CTX–Sharepoint 2013

La variable ctx es llamada variable de contexto, esta variable no está disponible en cada contexto de Sharepoint, por lo cual ten cuidado donde la usas. Por ejemplo: es muy usada en display templates de Search (link). En las páginas de forms de las listas/librerías (New, Edit y Display forms) y layouts (ej: site settings) NO suele estar definida esta variable. En las home page/wiki pages suele estar disponible. En las vistas de las listas también suele estar disponible.LO cual cómo les decía revisen donde la pueden usar. En el App Model tampoco está disponible obviamente.

Es una propiedad de read-only solamente, es decir sólo puedo leer la información de la misma. Para verla, abrimos la developer tools del IE (F12) y en la consola escribimos ctx

image

image

image

image

Con respecto a las funciones podemos tener las siguientes:

image

Voy a comentar las más importantes propiedades o funciones.

Por ejemplo si yo estoy en una vista de la lista podemos ver las propiedades.

Si en las propiedades avanzadas de la lista, marco/desmarco algunas propiedades, veo las propiedades avanzadas de la variable

image

Variable ContentTypesEnabled –> true

image

image

image

AllowCreateFolder –> undefined

image

image

AllowGridMode  --> false

image

image

EnabledMinorVersions –> true

Si yo selecciono dos items, me aparecerá la información en la propiedad “CurrentSelectItems”

image

También podemos obtener las urls de los forms de new/edit/display

image

image

Podemos ver la cantidad de items de la página de la vista (TotalListItems), el GUID de la View (propiedad view) y el nombre de la vista (ViewTitle). La propiedad verEnabled hace referencia si está habilitado el versionado (1) o no (0).

image

Después tenemos las propiedades listName  (guid de la lista), listTemplate (101 es una librería), listTitle (nombre de la libreria) y listUrlDir (url relativa de la librería)

image

Otra propiedad importante es ListSchema, la cual tiene todo el esquema propio de la libreria:

DefaultItemOpen = 1 –> es cuando seteas Open in the browser en las propiedades avanzadas de la librería

image

Después tenes todas propiedades propias del sitio: HttpRoot, CurrentLanguage, CurrentUICultureName, etc. Otras propiedades importantes son CurrentUserId (es el ID de la User Information List) y CurrentUserIsSiteAdmin.

image

Hay un montón de propiedades más, pero para finalizar voy a hacer uso de la propiedad ListData

image

La cual permite recorrer todas las filas de la view actual, y procesar los campos.

Por ejemplo. ctx.ListData.Row[0]

image

si yo escribo lo siguiente: alert(ctx.ListData.Row[0].FileLeafRef)

image

Una propiedad muy útil es : PermMask, que define que permisos tiene el usuario actual sobre ese item específico (row

image

FullMask = 0x7FFFFFFFFFFFFFFF (Grant all permissions). En este link tienen una lista de mask de permisos.

viernes, 15 de agosto de 2014

Qué librerías necesitamos para poder usar Client Object desde una página html en Sharepoint 2013?

Supongamos que subimos una página HTML a nuestro Sharepoint por algún motivo, por ej: para mostrarla en un popup por ejemplo con la librería FancyBox (http://fancyapps.com/fancybox/), y  necesitamos usar client object para mostrar información de una lista de Sharepoint.

Qué librerías de Sharepoint necesitamos para poder utilizar Client Object? Necesitamos las siguientes:

<script type="text/javascript"  src="_layouts/15/init.js"></script>
<script type="text/javascript" src="_layouts/15/MicrosoftAjax.js"></script>
<script type="text/javascript" src="_layouts/15/SP.Core.js"></script>
<script type="text/javascript" src="_layouts/15/sp.runtime.js"></script>
<script type="text/javascript" src="_layouts/15/sp.js"></script>

Supongamos que usamos jquery cómo librería externa. Podemos hacer lo siguiente para usar correctamente client object.

jQuery(document).ready(function($) {

    ExecuteOrDelayUntilScriptLoaded(function () {retrieveCustomersFromSharepoint();}, "sp.js");
   
});

function retrieveCustomersFromSharepoint()
    var clientContext = new SP.ClientContext("http://url_website");
    var oList = clientContext.get_web().get_lists().getByTitle('Customers');
    var camlQuery = new SP.CamlQuery();
    camlQuery.set_viewXml('<View><Query><Where><Eq><FieldRef Name="Title" /><Value Type="Text">' + cliente +'</Value></Eq></Where></Query></View>');
   
    this.collListItem = oList.getItems(camlQuery);       
    clientContext.load(collListItem);
    clientContext.executeQueryAsync(
        Function.createDelegate(this, this.onQuerySucceeded),
        Function.createDelegate(this, this.onQueryFailed)
    );
}

function onQuerySucceeded(sender, args) {
    var listItemInfo = '';
    var listItemEnumerator = collListItem.getEnumerator();
    while (listItemEnumerator.moveNext()) {
        var oListItem = listItemEnumerator.get_current();
        alert(oListItem.get_item('Title'));
    }   
}

function onQueryFailed(sender, args) {
    alert('Request failed. Contactese con Soporte Sharepoint ' + args.get_message() + '\n' + args.get_stackTrace());
}

Este ejemplo sirve también para PHP/JAVA/etc

domingo, 21 de abril de 2013

Links útiles #37 Sharepoint 2013

1-Obtener propiedades del user profile mediante una App

El siguiente link explica como crear una App para Sharepoint 2013 y Sharepoint Online para obtener información del usuario logueado.

Figure 2

http://code.msdn.microsoft.com/officeapps/SharePoint-2013-Work-with-99d43c17

2-Drive / Dropbox a Office 365

El artículo nos explica las diferentes posibilidades de migrar contenido desde Drive de Google y Dropbox a Office 365.

http://sharepoint-community.net/profiles/blogs/office-365-and-google-dropbox-document-import-user-experience

3-Introducción a Duet Enterprise Online con Sharepoint y SAP

http://technet.microsoft.com/en-us/library/dn144962.aspx

Duet Enterprise Online deployment diagram

4-Integración de reportes de PowerView usando PageViewer Web Part

El artículo nos explica como integrar un reporte de PowerView mediante un web part de page viewer y mediante un web part de silverlight

http://blogs.msdn.com/b/himanshu1/archive/2013/03/04/integrate-power-view-with-sharepoint-using-web-parts.aspx

5-Acceder a un Term Store mediante SP.Taxonomy.js

En el link encontrará varios ejemplos del uso de javascript para consumir taxonomías de Sharepoint 2013, mediante la librería SP.Taxonomy.js

http://cann0nf0dder.wordpress.com/2013/04/09/accessing-taxonomy-term-store-with-jsom/