SharePoint Meeting Workspace: OOB approval workflow to copy list items from one list to another
A Meeting Workspace is a Web site that can be used to gather all the information and materials that are needed for one or more meetings. This can include information about the date, time, and place of the meeting, a library of shared documents, and lists of agenda items and objectives for the meeting, tasks assigned, and decisions taken.
This provides few lists OOB for creating tasks, storing documents, and recording decisions etc. one small suggestion for those who want to use this template, this template will not support much customization. For example customizing this site like changing home page in SharePoint designer or modifying the OOB list column names may cause the site to behave in a weird manner.
This template supports both single meeting workspace or recurrent meetings workspace i.e. multiple meetings with in the same workspace as shown below.
In case of recurrent meetings, Instance Id will be maintained for each occurrence. What does this mean?
If we select May 22, 2012 occurrence as shown above, it will maintain a respective Instance Id for the selected occurrence. This instance id is created based on the date of the selected occurrence. If we have only one meeting in the site then the Instance Id is -1.To know more about this instance id, click here
All the lists in side this site template will store list items based on the current selected recurrence. This means, if we store two records in the objective list for the selected occurrence they will not be visible for the other occurrences. Anyhow we have an option to see all the meetings inside the list/library also :)
A SharePoint site by using Meeting workspace template can be created by using Outlook also, to know how to do, see my blog here.
To Modify Home page:
However If you still want to change modify home page, we can do that by using Content Editor webpart and JQuery. Put the following code in content editor webpart on the home page. This code adds two links to the left nav by append the required html to the existing left panel.
<script src="https://blogs.msdn.com/_layouts/jquery-1.6.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#s4-leftpanel-content").append("<div
class='s4-ql'><div class='menu vertical menu-vertical'><ul
class='root static'><li class='static'><a class='static menu-item' href='Lists/All%20Tasks/My%20Tasks.aspx'><span
class='additional-background'><span class='menu-item-text'>My
Tasks</span></span></a></li><li
class='static'><a class='static menu-item' href='pages/Reports.aspx'><span
class='additional-background'><span class='menu-item-text'>Reports
(All
Tasks)</span></span></a></li></ul></div></div>");
});
</script>
This script requires “jquery-1.6.2.min.js” file to be present in the _layouts folder.
This site can’t be saved with content. That means, if we save this site as template it will not include the content inside lists, libraries, etc, but it will have content editor webpart and any text/HTML code inside it. That is the reason I selected Content Editor webpart for adding links in the home page
Approval Workflow to copy items from one list to other.
My requirement says based on approving the records in list A, list items from List B should get copied to List C. This copy may include copying multiple items also. To copy one item at a time, we have OOB SharePoint designer action. But to do this bulk copying, I preferred JQuery. The following are the steps I followed to do this.
- Create an OOB approval workflow which will approve the records in List A by using SharePoint designer.
- Copying from List B to List C can be implemented by using JQuey(See the code below with comments).
- Now the toughest task comes here to invoke copying part once the records in List A got approved.
- That means calling Jquery from workflow which is not possible.
- Put a button on click of which approval window will be opened by using JQuery. Once the user clicks on approve in approval window, this event will be captiured in the JQuery and the copying task should be done in JQuery.
Code for the button click to copy and approve
This code is included as part of content editor webpart
<div>
<script src="https://blogs.msdn.com/_layouts/jquery-1.6.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
// To make sure the required JS files got loaded
ExecuteOrDelayUntilScriptLoaded(EnsureScriptsLoaded, "jquery-1.6.2.min.js");
ExecuteOrDelayUntilScriptLoaded(getWebSiteData,"sp.js");
ExecuteOrDelayUntilScriptLoaded(EnsureScriptsLoaded,"sp.ui.dialog.js");
function EnsureScriptsLoaded() {
//Blank
method -To ensure script files loaded
}
// This click is triggered on button click which will do both approve and copy jobs
function ApproveTasks() {
// Get the context object
var context = new SP.ClientContext.get_current();
var web = context.get_web();
site = context.get_site();
context.load(site);
var meetingList = web.get_lists().getByTitle('ListA');
var query = SP.CamlQuery.createAllItemsQuery();
allItems = meetingList.getItems(query);
context.load(allItems);
context.executeQueryAsync(Function.createDelegate(this, this.success), Function.createDelegate(this, this.failed));
}
function failed(sender, args)
{
alert("failed. Message:" + args.get_message());
}
function success(sender, args)
{
var recordCount = allItems.get_count();
if(recordCount >0)
{
var meetingItem = allItems.itemAt(0);
currentWeb = url of the current web;
var siteUrl = url of the current site;
this.ItemID =Id of the cuurent item;
this.itemURL = Item URl;
this.workflowName = "Name of the workflow";
this.listId = meetingItem.get_item('GUID');
this.itemURL= decodeURIComponent(this.itemURL);
this.workflowName= decodeURIComponent(this.workflowName);
this.itemURLID= itemURL + ItemID + "_.000";
//Get Context details
var thisSite = $().SPServices.SPGetCurrentSite();
var currentUser = $().SPServices.SPGetCurrentUser();
currentUser = currentUser.toLowerCase();
//AJAX call to get current user task
$().SPServices({
operation: "GetToDosForItem",
item:itemURLID,
async:false,
completefunc: function (xData, Status) {
var respToDoID = '';
var respToDoListID = '';
var respToDoContentTypeId = '';
var isTaskFound = false;
var respToDoStatus = '';
var isTaskFormOpened = false;
$(xData.responseXML).find("[nodeName='z:row']").each(function
() {
isTaskFound = true;
respToDoStatus = $(this).attr("ows_Status");
//Checking assigned task status
if (respToDoStatus == 'Not Started' || respToDoStatus == 'In Progress')
{
var respToDoAssignedTo = $(this).attr("ows_AssignedTo");
var grp = respToDoAssignedTo.substring(respToDoAssignedTo.indexOf(';#')+ 2);
respToDoAssignedTo = respToDoAssignedTo.toLowerCase();
respToDoID = $(this).attr("ows_ID");
respToDoListID = $(this).attr("ows_TaskListId");
respToDoContentTypeId = $(this).attr("ows_ContentTypeId");
var u = thisSite +'/_layouts/WrkTaskIP.aspx?List=' + respToDoListID + '&ID=' + respToDoID +'&ContentTypeId=' + respToDoContentTypeId + '&IsDlg=1';
//Approval window popup will open
SP.UI.ModalDialog.showModalDialog({title: "Approve Request Process", width: 700, height: 470, url: u,allowMaximize: false, dialogReturnValueCallback:DialogCallbackMethod });
isTaskFormOpened = true;
}
});
if(isTaskFound == false) {
alert('No tasks found to approve');
}
else if (isTaskFound == true && respToDoStatus == 'Completed' && isTaskFormOpened == false) {
alert('No tasks found to approve');
}
}
});
}
else
{
alert('Workflow not started on the meeting details item. Contact system administrator');
}
}
else
{
alert('No records in found');
}
}
// Custom callback function after the dialog is closed
function DialogCallbackMethod(dialogResult, returnValue) {
// If user clicks on approve
if(dialogResult == 1) {
// Copy list items from List B to List C
CopyTasksToAllTasks();
}
}
function CopyTasksToAllTasks() {
context = new SP.ClientContext.get_current();
var web = context.get_web();
list = web.get_lists().getByTitle('ListB');
context.load(list);
destlist = web.get_lists().getByTitle('ListC');
context.load(destlist);
var meetingDetails = web.get_lists().getByTitle('ListA');
context.load(meetingDetails);
var query = SP.CamlQuery.createAllItemsQuery();
meetingdetailsItems = meetingDetails.getItems(query);
context.load(meetingdetailsItems);
allItems = list.getItems(query);
fields = list.get_fields();
context.load(fields);
context.load(allItems);
context.executeQueryAsync(Function.createDelegate(this, onListItemsLoadSuccess), Function.createDelegate(this, onListQueryFailed));
}
function onListItemsLoadSuccess(sender, args) {
var TextFiled = "";
var ListEnumerator = allItems.getEnumerator();
var meetingItem = meetingdetailsItems.itemAt(0);
var status = meetingItem.get_item('WorkflowStatus');
while(ListEnumerator.moveNext())
{
var item = ListEnumerator.get_current();
var itemCreateInfo = new SP.ListItemCreationInformation();
// add an empty list item to List C
newItem = destlist.addItem(itemCreateInfo);
// copy title from List B to List C. Repeat the same
for all the fileds
var title = item.get_item('Title');
if(title != null)
{
newItem.set_item('Title', title);
}
// Update the new item
newItem.update();
context.executeQueryAsync(Function.createDelegate(this, onListItemsLoadSuccess1),
Function.createDelegate(this, onListQueryFailed1));
}
}
function onListItemsLoadSuccess1(sender, args) {
// To reload the page on successful copy
SP.UI.ModalDialog.RefreshPage(SP.UI.DialogResult.OK);
}
function onListQueryFailed1(sender, args) {
alert("failed. Message:" + args.get_message());
}
function onListQueryFailed(sender, args) {
alert("failed. Message:" + args.get_message());
}
</script>
<a id="CopyTasksListToAllTasksList" onclick="ApproveTasks();" href="#">
<img title="Copy" id="imgCopyTasksListToAllTasksList" src="https://blogs.msdn.com/_layouts/images/icodct.gif" border="0" alt=""/> Approve Request</a></div>