SharePoint 2010. Iniciar un flujo de trabajo en múltiples elementos de una lista

En SharePoint 2010 tenemos una opción para seleccionar varios elementos en una lista pero cuando se seleccionan varios elementos, la ribbon sólo permite eliminar elementos y configurar el envío alertas, pero ¿dónde está el comando de flujo de trabajo?

Por definición, para iniciar un flujo de trabajo en un elemento de lista, tienes que hacerlo a través de la página de inicio de flujo de trabajo y, si el workflow tiene un formulario de inicialización, también tendrás que escribir estos parámetros. Con estas limitaciones, SharePoint no permite a los usuarios iniciar un flujo de trabajo en múltiples elementos, pero ¿por qué no puedo hacerlo con un flujo de trabajo sin parámetros?

Creo que esto es una característica que falta en SharePoint 2010 porque podríamos hacerlo usando la API de SharePoint o los servicios Web sin problemas. Y ahora ¿qué podemos hacer para implementar esta funcionalidad?

 

Primero tenemos que crear un comando de la ribbon mediante una acción personalizada y en esta acción, tenemos dos opciones para comenzar el flujo de trabajo, la primera de ellas es utilizando una página de aplicación, pasando los elementos seleccionados como parámetros y utilizar el servidor api para iniciar el proceso y la segunda opción, más flexible y elegante, usando JavaScript y los servicios Web de SharePoint para iniciar el flujo en cada uno de los elementos seleccionados.

SPServices al recates!!

Como bien saben, SPServices en una librería de jQuery que encapsula los servicios Web de SharePoint de forma que podamos utilizarlos con bastante sencillez. SPServices tiene un espacio de nombre para Workflow con operaciones que nos permiten iniciar un flujo (StartWorkflow), inclusive si este tuviera parámetros.

Es tan fácil de usar, sólo necesitamos la URL del elemento, el id de la plantilla de flujo de trabajo y, si fuera necesario, los parámetros.

$().SPServices({

operation: “StartWorkflow”,

item: currentItemURL,

templateId: workflowGUID,

workflowParameters: workflowParams,

async: true,

completefunc: function () {

SP.UI.Notify.addNotification(“Workflow process started on selected item.”, false);

}

});

 

Para obtener el id de la plantilla, SPServices nos proporciona otra función (GetTemplatesForItem) que nos devuelve todos los flujos asociados a un elemento. Todo lo que tenemos que hacer es obtener las plantillas y encontrar nuestro flujo por nombre.

$().SPServices({

operation: “GetTemplatesForItem”,

item: itemURL,

async: true,

completefunc: function (xData, Status) {

var currentItemURL = this.item;

$(xData.responseXML).find(“WorkflowTemplates > WorkflowTemplate”).each(function (i, e) {

if ($(this).attr(“Name”) == “Invoice Approve”) {

var guid = $(this).find(“WorkflowTemplateIdSet”).attr(“TemplateId”);

if (guid != null) {

workflowGUID = “{“ + guid + “}”;

//En este punto, tenemos nuestros id y tenemos que hacer el inicio del workflow }

}

}

}

})

 

Ahora, en el método de la acción personalizada, tenemos que recorrer todos los elementos seleccionados y utilizar el método StartWorkflow, de SPServices, para cada uno.

function StarSignWorkflow(listId) {

RemoveAllStatus(true);

waitDialog = SP.UI.ModalDialog.showWaitScreenWithNoClose(‘Starting approval workflow process on selected item’, ‘Please, wait until we finished this long operation.’, 76, 400);

 

//Get the selected items

clientContext = new SP.ClientContext.get_current();

var web = clientContext.get_web();

var list = web.get_lists().getById(listId);

var items = SP.ListOperation.Selection.getSelectedItems(ctx);

totaSelItems = items.length;

 

//Because only have items Id, we need to use Client Object Model to get EncodeAbsUrl.

var query = new SP.CamlQuery();

var queryString = ‘<View><Query><Where><In><FieldRef Name=”ID”/><Values>’;

for (index in items) {

var valueString = ‘<Value Type=”Integer”>’ + items[index].id + ‘</Value>’;

queryString = queryString + valueString;

}

query.set_viewXml(queryString + ‘</Values></In></Where></Query></View>’);

this.collListItems = list.getItems(query);

clientContext.load(collListItems, ‘Include(EncodedAbsUrl)’);

//In the success callback, we’ll have all the selected items with the absolute url.

clientContext.executeQueryAsync(Function.createDelegate(this, this.onInitProcessSuccess), Function.createDelegate(this, this.onInitProcessFail));

}

function onInitProcessSuccess() {

var listItemEnumerator = this.collListItems.getEnumerator();

 

//If our workflow has default init param, we can provide it in this way to run workflow with default values.

var workflowParams = “<Data><Approvers></Approvers><NotificationMessage></NotificationMessage>” +

“<DurationforSerialTasks></DurationforSerialTasks><DurationUnits></DurationUnits>” +

“<CC></CC><CancelonRejection></CancelonRejection><CancelonChange></CancelonChange>” +

“<EnableContentApproval></EnableContentApproval></Data>”;

try {

var counter = 1;

var total = totaSelItems;

 

//Traverse all the selected items

while (listItemEnumerator.moveNext()) {

var oListItem = listItemEnumerator.get_current();

var itemURL = oListItem.get_item(‘EncodedAbsUrl’);

var workflowGUID = null;

 

//Before start the workflow, we used GetTemplatesForItem to get Workflow Template Id.

$().SPServices({

operation: “GetTemplatesForItem”,

item: itemURL,

async: true,

completefunc: function (xData, Status) {

var currentItemURL = this.item;

$(xData.responseXML).find(“WorkflowTemplates > WorkflowTemplate”).each(function (i, e) {

if ($(this).attr(“Name”) == “Invoice Approve”) {

var guid = $(this).find(“WorkflowTemplateIdSet”).attr(“TemplateId”);

if (guid != null) {

workflowGUID = “{“ + guid + “}”;

$().SPServices({

operation: “StartWorkflow”,

item: currentItemURL,

templateId: workflowGUID,

workflowParameters: workflowParams,

async: true,

completefunc: function () {

if (total == counter) {

if (waitDialog != null) {

waitDialog.close();

}

SP.UI.Notify.addNotification(“Started workflow approved process for selected invoice.”, false);

window.location.reload();

}

counter++;

}

});

}

}

});

}

});

}

} catch (e) {

if (waitDialog != null) {

waitDialog.close();

}

AddStatus(“There is an exception. Error: “ + e.message, “red”);

}

}

Como hemos visto, tenemos una forma sencilla de permitir a nuestros usuarios iniciar un flujo en varios elementos a la misma vez, gracias a SPServices que nos facilita la vida para trabajar con SharePoint desde cliente.

 

Saludos a todos…

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *