Thursday, November 24, 2016

Query String (URL) Filter Web part

The web part is very useful to display the list results based on filters applied. You can create a page in Site Pages library. Add list view web part to the page and below that add 'Query String (URL) Filter ' Web Part below that. In Web Part settings for Query String (URL) Filter Web part, specify the column for which you need to apply filter.

Follow the below links
https://support.office.com/en-us/article/Connect-a-Query-String-URL-Filter-Web-Part-to-another-Web-Part-8fd0107f-4889-451b-a7f7-d1996e12a8d1?ui=en-US&rs=en-US&ad=US&fromAR=1

Wednesday, November 23, 2016

Read value of controls in SharePoint form

Hi folks,

I got a pre-defined function which helps to read value of controls in SharePoint form. To find a control in SharePoint from client side Javascript we normally use the getTagFromIdentifierAndTitle function.

function getTagFromIdentifierAndTitle(tagName, identifier, title) {
   var len = identifier.length;
   var tags = document.getElementsByTagName(tagName);
    
   for (var i = 0; i < tags.length; i++) {
  var tempString = tags[i].id;
 if (tags[i].title == title && (identifier == "" || 
          tempString.indexOf(identifier) == tempString.length - len))
        {
           return tags[i];
 }
   }
   return null;
}
Tag is the html tag used to define the control, Identifier is the type of the control and title is the name of the control. Below are basic tag and identifiers of the server side controls.
Control                 Tag               Identifier
Panel                 div  
Label                 label  
Button                 input               button
Link Button         href  
Hyperlink         href  
Image Button         input               image
Textbox                 input               text
Textbox (Password) input               password
Textbox (Multiline) Input               textarea
DropDownList         select  
Listbox                 select  
RadioButton         input               radio
Checkbox         input               checkbox
File                 input               file

Please find the link below for more information
https://workflowssimplified.wordpress.com/2011/09/15/gettagfromidentifierandtitle-function/ 


Wednesday, October 26, 2016

JavaScript Navigation tricks in SharePoint forms

1. Navigate from NewForm.aspx to DisplayForm.aspx in SharePoint after clicking Save button.


Under PreSaveAction function add the below steps

var URL = location.pathname.replace('NewForm.aspx','DispForm.aspx');
if(GetUrlKeyValue('IsDlg')==='1'){
URL+="?IsDlg=1";
}
$("#aspnetForm").attr('action',location.pathname+"?Source="+URL);
return true;





2. Navigate from DisplayForm.aspx in one list to NewForm.aspx in another list with few of the fields populated.


HTML:
<span  style="font-size:x-large">To continue to phase 3, please <a href="#" target="_blank" id="Phase3Link">click here</a>.</span>

JavaScript:
$(document).ready(function(){
var requestID = $("#RequestID").text();

var phase3NewFormURL = "https://accobrands.sharepoint.com/sites/Departments/USOpsSC/OracleISRT/Lists/IMCRP3/P3NewForm.aspx?ReqId=" + requestID + "&Source=https://accobrands.sharepoint.com/sites/Departments/USOpsSC/OracleISRT/Pages/MyReqs.aspx";

$("#Phase3Link").attr("href", phase3NewFormURL);
//SetItemNumber(requestID, itemNumberTCell);

});


In P3NewForm.aspx

$(document).ready(function(){
//$("#imStatus").hide();
GetCurrentUserName(false, false);
/* Parse query string and set Request ID */
var requestIDQueryString = GetUrlKeyValue("ReqId");
var requestIDField = $("input[title='Request ID']");
requestIDField.val(requestIDQueryString);

requestIDField.prop("readonly", "true");
});


Wednesday, October 19, 2016

FIX: SharePoint 2013 Workflow recursion prevention – Part 2

Following FIX: SharePoint 2013 Workflow recursion prevention – Part 1, this post will walk you through the processes of designing your workflow that creates a list item on another list and invokes the workflow associated with that list using the new REST APIs released through SharePoint 2013 May 2014 CU as pointed out in part 1 of this series.  If you haven’t read through part 1 of this series I suggest you do to get some background that will help you appreciate this post.
The scenario:
List1 has a workflow Workflow1 associated with it.
Workflow1 can be set to auto-start on item adding/updating or set to manually start or both, it doesn’t matter.
image
Workflow1 is designed to create a list item on List2.
image
List2 has a workflow Workflow2 associated with it.
Workflow2 should have manually start workflow option enabled. (Allow this workflow to be manually started)
image
Workflow2 simply logs the title of the list item in workflow history list.
image
NOTE: Both Workflow1 and Workflow2 are built on 2013 workflow platform.
Publish both the workflows and create an item on List1.  Manually start Workflow1 on the list item and you should see that it completes successfully.
Now browse to List2 and you will see that a new list item was successfully created by Workflow1.
image
The problem:
But Workflow2 would never start off.  Refer part 1 of this series, check ULS logs and you’ll see Workflow2 didn’t start because of workflow recursion prevention.
Fix:
The fix is to leverage the new REST APIs exposed to start off Workflow2 from Workflow1.  Let’s open Workflow1 in SharePoint Designer’s workflow editor.
We drop a “Build Dictionary” action just above the create item in list action with the following name/value pairs of type string.
accept: application/json;odata=verbose
content-type: application/json;odata=verbose
image
Choose the dropdown against “(Output to Variable: dictionary)” and create a variable to type Dictionary named “ReqHeader”.
image
Choose the dropdown against “(Output to Variable: create)” and create a new variable named “NewItemGuid”.  It will be of type GUID.
image
Drop a “Call HTTP Web Service” action after the create item in list action.
image
Choose the dropdown against “(Output to Variable: dictionary)” and create a variable to type Dictionary named “ReqHeader”.
image
Choose the dropdown against “(Output to Variable: create)” and create a new variable named “NewItemGuid”.  It will be of type GUID.
image
Drop a “Call HTTP Web Service” action after the create item in list action.
image
Choose the dropdown against “(Output to Variable: dictionary)” and create a variable to type Dictionary named “ReqHeader”.
image
Choose the dropdown against “(Output to Variable: create)” and create a new variable named “NewItemGuid”.  It will be of type GUID.
image
Drop a “Call HTTP Web Service” action after the create item in list action.
image
Choose “Properties” option from the context menu of “Call HTTP Web Service” action.
image
Set “RequestHeaders” to the request header variable you created and create a new variable of type dictionary named “RespContent” for “ResponseContent” as shown below.  Hit OK.
image
Drop a “Get an Item from a Dictionary” action after “Call HTTP Web Service” action and click “item by name or path” hyperlink.  In the editor type d/results(0).
Click the dictionary hyperlink and choose “Variable: RespContent” from the dropdown.  Click the item hyperlink and again choose “Variable: RespContent” from the dropdown.  End result will be.
image
There are plenty of articles out there that talk about how to parse the JSON to get to the actual data we need so I am not going to cover that here.  But remember we can use Fiddler to determine the structure of JSON result and we’ll use that knowledge to decide on how we will get to the result we need (for e.g., d/results(0)).
What we did above is that we want the value at d/results(0) from the RespContent dictionary variable we get back from the web service call.  We are then storing the result again back in RespContent because the result is also of type dictionary.
Drop another “Get an Item from a Dictionary” action.  Click on “item by name or path” hyperlink and type Id.  Click “dictionary” hyperlink and choose “Variable: RespContent”.  Click the item hyperlink in “(Output to item)” and create a new variable named “NewItemId” of type integer as shown below.
image
We did all these to get the ID (the sequence number) value of the list item we just created.  Phew!!!  This is because we need to know the ItemID of the list item we just created as we need to pass it to the StartWorkflowOnListItemBySubscriptionId REST method later.  But we are just 30% into our design Smile
The other parameter that StartWorkflowOnListItemBySubscriptionId needs is the workflow SubscriptionId.
We drop another “Call HTTP Web Service” action and construct our next REST call.  This time we call/_api/web/lists/GetByTitle(‘List2’).  We set the same “ReqHeader” variable to this call.  And set the same “RespContent” variable as we did before.  The end result you should have in “Call HTTP Web Service” dialog is shown below.
image
And in designer we should see.
image
We then add another “Get an Item from a Dictionary” action.  Ask for d/Id from “RespContent” variable and assign the output to a new variable named “List2Guid” of type GUID as shown below.
image
Now the variable “List2Guid” will have the GUID of List2.  We need this to get the workflow subscriptionId that we can get by calling an already available REST API called/_api/SP.WorkflowServices.WorkflowSubscriptionService.Current/EnumerateSubscriptionsByList.
We now drop another “Call HTTP Web Service” action and set it up get all workflow subscriptions.  Here’s how string builder should look like for this call.
image
And we set the “HTTP method” option for this “Call HTTP Web Service” action to “HTTP POST” as shown below.
image
We should now have the workflow design as shown below.
image
Now we have a tricky situation where we need to get the subscriptionId of the exact workflow that we are interested to start off.  This is where Fiddler is very helpful.  Again I’ll defer to the plethora of articles available online that tells us how to do a GET, POST REST calls using Fiddler.  But I am going to rush on this piece a bit.
Through Fiddler (by submitting a POST request to the same REST method EnumerateSubscriptionsByList, we see the following output.
image
Workflow2 happens to be the 3rd in the list of workflows associated to List2 so I can get that out using the 2nd index.  So we drop two more “Get an Item from a Dictionary” actions.  In the first action we ask for d/results(2) from “RespContent” and we store the output again in “RespContent”.  In the second action we ask for Id which happens to be the SubscriptionId of Workflow2 on list List2 from “RespContent” again and store the result in a new variable named “SubscriptionId” of type GUID.  Our workflow design should now look like below.
image
Now we are at the final stage where we will start the workflow.
Drop our last “Call HTTP Web Service” action and call the new/_api/SP.WorkflowServices.WorkflowInstanceService.Current/StartWorkflowOnListItemBySubscriptionId REST method by passing in the SubscriptionId and NewItemId variables.  Our string builder dialog should look like the below.  (Ensure the parameter names of this method is exactly as it is shown below and that the values are enclosed within single quotes).
image
This will again be a POST request.
image
After setting the “ReqHeader” correctly using the “Properties” context menu option for the last “Call HTTP Web Service” action, we drop a “Set Workflow Status” action.  The completed Workflow1 should look like below.
image
That’s it!!
We Save/Publish our workflow, go to List1 and create a new item.  Start off Workflow1 manually on that new item.  It should complete successfully.  Then we go to List2 and we should see that a new item is created and Workflow2 was trigged off too.
image
If we click on “Stage 1”, we’ll see that Workflow2 logged the message as we designed.
image
I hope the information in this post was useful.  Please check out the next part SharePoint 2013 Workflow recursion prevention – Part 3 to achieve the above objective from a Visual Studio SharePoint 2013 Workflow.

Friday, September 23, 2016

String Utility Actions in SPD 2013

Hi Folks,

I'll share my experience how I used different string utility action to implement the requirement.

1. Split the string in date/time field to get the date part

Start Date: 9/22/2016 5:00:00 AM

Here the date/time value is 9/22/2016 5:00:00 AM and I need to get the date part i.e. 9/22/2016. Check the below steps.

Step1: From the string I need to find a character which splits date and time. I could see a space splits it. I used the action "Find Substring in string" and made it to look for space.


Step2:  I used the action "Extract Substring from the start of string" to extract the date part.

The date part got stored in the variable named as "substring1".

Wednesday, September 7, 2016

Hide Aprove/Reject button from the ribbon

Hi Folks,

I got a requirement to hide 'Approve/Reject' button but the ribbon in Display form. I've written a short JavaScript code to achieve the functionality.

1. Use developer tools in Chrome to get the ribbon id.



<a class="ms-cui-ctl-medium" id="Ribbon.ListForm.Display.Manage.ApproveReject-Medium" onclick="return false;" href="javascript:;" mscui:controltype="Button" aria-describedby="Ribbon.ListForm.Display.Manage.ApproveReject_ToolTip" role="button" unselectable="on"><span class="ms-cui-ctl-iconContainer" unselectable="on"><span class=" ms-cui-img-16by16 ms-cui-img-cont-float ms-cui-imageDisabled" unselectable="on"><img class="" style="top: -313px;left: -1px;" unselectable="on" src="/_layouts/15/1033/images/formatmap16x16.png?rev=44"></span></span><span class="ms-cui-ctl-mediumlabel" unselectable="on">Approve/Reject</span></a>



2. Create a custom display form for a list and add the below code.
<script type="text/javascript" src="https://accobrands.sharepoint.com/ITCompliance/SiteAssets/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="https://accobrands.sharepoint.com/ITCompliance/SiteAssets/sputility.min.js"></script>
<script type="text/javascript" src="https://accobrands.sharepoint.com/ITCompliance/SiteAssets/url.js"></script>
<script type="text/javascript">
    function hideEdit() {
        var edit = document.getElementById("Ribbon.ListForm.Display.Manage.ApproveReject-Medium");
        edit.style.display = "none";
    }       
    _spBodyOnLoadFunctionNames.push("hideEdit");
</script>

3. Save the form and see the result by clicking "Preview in browser".

Monday, August 1, 2016

Use Managed Metadata field value in SharePoint Designer Workflow emails

Hi Folks,

I've struggled a lot in using a value of Managed Metadata field value in SPD Workflow emails as it has issues with workflows and calculated fields. We can't read the Managed Metadata field values in Calculated column even.

But I got a way to use its value at least in SPD Workflow emails. Lets begin.

Create a SharePoint list say "Terms" with 2 fields: Title (Type: Single Line of Text) and TermCol (Type: Managed Metadata). Assign "TermCol" field to a term set you've created for business terms.

Then create a SPD workflow named "WF1 Terms".

1. Create a variable called 'Term' of type String. Within workflow, 2 fields will be created for "TermCol" field: TermCol and TermCol_0. We'll use TermCol_0 to read the value.

2. Set workflow variable 'Term' to value of 'TermCol_0'.




3. The value stored in variable 'Term' is like EFG-1DENA-NICOLE|19bd6c3e-0fa4-4b98-98cf-ca6da92e2bf0. The exact value is separated from its ID by "|". We need to split the values to read only the value in the workflow email.

4. Use the action "Find Substring in String" to split the value and ID in workflow variable 'Term'.



5. Use the action "Extract Substring from the start of string" to read only the value of Managed Metadata field.



6. Add the email step and use the value of workflow variable 'Term' to read the value of Managed Metadata field.

7. Run the workflow. It'll provide you the value of Managed Metadata field in the email generated via. workflow.

Monday, June 27, 2016

Get Datepart in SharePoint Designer Workflow

Hi Folks,

Yesterday, I got a task to split the date and get the day from there. I got a very good link to split date into 3 parts: Year, Month & Day.

First you have to start by asigning a new workflow string variable to a date value, and make sure to select the ISO Formatted option for the return field as parameter. This will set the string variable to something like 2010-12-28 according to the ISO format(yyyy-mm-dd).

We can now use the Utility Actions for string variables to extract our Year, Month and Day.

Screenshot

With this we can store the year in 'DatePartYear', month in 'DatePartMonth' & day in 'DatePartDay' variables and use it accordingly.

For reference, Please use the below link.
http://weblogs.asp.net/wesleybakker/get-datepart-in-sharepoint-designer-workflow 

Sunday, April 17, 2016

SPServices Code to update list items

Hi Folks,

I did an enhancement in my project to update multiple list items using jQuery SPServices. I tried very hard to use EcmaScript to update multiple list items but unfortunately it didn't work out. Finally, I had to depend on my old buddy i.e. SpServices to implement it. Basically, I've a parent list with a Primary Key which acts as a Foreign Key in Child list. From Parent list's Editform.aspx, I've to update the items based on 1 Yes/No field value in parent list which will update the Yes/No field in child list items. The Key is helpful in doing that but we've to use ID field to update items.
Here's the code below.

<script type="../SiteAssets/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="../SiteAssets/sputility.min.js"></script>
<script type="text/javascript" src="../SiteAssets/url.js"></script>
<script type="text/javascript" src="../SiteAssets/jquery.SPServices-2013.01.min.js"></script>
<script type="text/javascript" src="../SiteAssets/jquery.SPServices-2013.01.js"></script>


<script type="text/javascript">

var cuidSox;
var context;
var website;
var list;
var items;
var itemCount;
/*$(document).ready(function() {
});*/

function PreSaveAction(){

SP.SOD.executeFunc('sp.js', 'SP.ClientContext', SharePointReady);
// Update SOx list
return true;
}

function SharePointReady(){

cuidSox = $("input[title='Control UID']").val(); //Control UID from Sox control Master List which acts as Primary Key in Parent List and Foreign key in child list

if( $("input[id='ctl00_ctl40_g_48a5562b_7b23_4406_b69b_561200fe8c87_ff151_ctl00_ctl00_BooleanField']").is(':checked')) { 
    var queryXml = "<View><Query><Where><Eq><FieldRef Name = 'ControlUID'/><Value Type='Text'>" + cuidSox + "</Value></Eq></Where></Query></View>";
var query = new SP.CamlQuery();
query.set_viewXml(queryXml);
    context = new SP.ClientContext.get_current();
website = context.get_web();

list = website.get_lists().getByTitle('Monitoring List');
items = list.getItems(query);
context.load(items);
context.executeQueryAsync(onRequestSucceeded, onRequestFailed);
else{
//no action needed
}
}

function onRequestSucceeded() {
itemCount = items.get_count();
//alert(itemCount);  
var enumerator = items.getEnumerator();
while (enumerator.moveNext()) {           
var currentItem = enumerator.get_current();
var itemId = currentItem.get_item('ID');
//alert(itemId);
$().SPServices({
  operation: "UpdateListItems",
  async: false,
  batchCmd: "Update",  
  listName: "Monitoring List", 
  ID: itemId, //Without ID field it won't update the values based on parameter value. That's why with Control UID wasn't working before
  valuepairs: [["Retired",1]],
  debug: false,
  completefunc: function(xData, Status) {}
});

}

confirm(itemCount+" items got retired in Monitoring list");
}

function onRequestFailed(sender, args) {
        alert('Error: ' + args.get_message());
}


</script>


Preferred Links:

Wednesday, March 30, 2016

SharePoint Designer 2013 workflow loop to remove spaces

Hi Friends,

I wrote a workflow to generate a unique primary key which will reference all the SharePoint lists in site. However, I need to remove the whitespaces and zeros in the generated primary key.
I found the below link which provided a solution for that. I've also wrote the steps in case link got deactivated.
http://www.documentmanagementworkflowinfo.com/sharepoint-2013/sharepoint-designer-2013-workflow-loop-remove-spaces-string.htm 

You can use a SharePoint Designer workflow loop to loop through substrings in a string to remove any spaces that are embedded within the string, and then concatenate the strings with each other to be able to form a string that does not contain any spaces. In the example below, you are going to remove spaces from the string "SharePoint 2013 lists and libraries".


To use a SharePoint Designer workflow loop to remove spaces from a string:

1. In SharePoint 2013, create a new SharePoint list named MyList that has one column named Title.
2. In SharePoint Designer 2013, create a new List Workflow that runs on the MyList SharePoint list. Name the workflow RemoveSpacesFromStringWF and leave SharePoint 2013 Workflow selected as the Platform Type.
3. Create a local variable of type String named TextString1.
4. Add a Set Workflow Variable action to the SharePoint workflow, and configure it to say: 

(workflow step)
Set Variable: TextString1 to SharePoint 2013 lists and  libraries 

Note that there are two spaces between "and" and "libraries" (to test the removal of double spaces), and that an extra space was appended to the entire string to be able to find the last substring in the string.

5. Add a Find Substring in String action to the SharePoint workflow and configure it to say:

(workflow step)
then Find   in Variable: TextString1 (Output to Variable: index)

Here you are just trying to find the first space in the TextString1 variable.


6. Click to place the cursor below the last action you added, and then select Workflow > Insert > Loop > Loop with Condition, and configure the sentence for the loop to say: 

(workflow step)

The contents of this loop will run repeatedly while: Variable: index not equals -1


7. Click to place the cursor inside the loop, and then add an Extract Substring of String from Index with Length action to the SharePoint workflow, and configure it to say:

(workflow step)
Copy from Variable: TextString1, starting at 0 for Variable: index characters (Output to Variable: substring )


8. Create a local variable of type String named StringWithoutSpaces.

9. Click to place the cursor below the last action you added, and then select Workflow > Insert > Condition > If any value equals value, and configure the condition to say: 

(workflow step)
If Variable: substring is not empty


10. Add a Set Workflow Variable action inside the loop, inside of the If-Condition of the SharePoint workflow, and configure it to say: 

(workflow step)
Set Variable: StringWithoutSpaces to [%Variable: StringWithoutSpaces%][%Variable: substring%]

where you must use the String Builder dialog box to concatenate the strings that are stored in the variables.


11. Add a Do Calculation action inside the loop but outside of the If-Condition of the SharePoint workflow, and configure it to say: 

(workflow step)
then Calculate Variable: index plus 1 (Output to Variable: calc)


12. Add an Extract Substring from Index of String action inside the loop but outside of the If-Condition of the SharePoint workflow, and configure it to say:

(workflow step)
then Copy from Variable: TextString1, starting at Variable: calc (Output to Variable: TextString1)

13. Add a Find Substring in String action inside the loop but outside of the If-Condition of the SharePoint workflow, and configure it to say: 

(workflow step)
then Find   in Variable: TextString1 (Output to Variable: index)

Here you are trying to find the next space in what is left of the string stored in the TextString1 variable. This is also the last action within the loop. If the value of index is equal to -1, so no space is found, the looping will end; otherwise it will continue looping through the string stored in TextString1 until it does not find any more spaces.

14. Add a Log to History List action outside the loop to the SharePoint workflow, and configure it to say: 

(workflow step)
then Log Variable: StringWithoutSpaces to the workflow history list

15. End the SharePoint workflow with a Go to a stage action.
16. Configure the SharePoint workflow to start automatically when an item is created.
17. Publish the workflow to SharePoint 2013.


In SharePoint 2013, navigate to the MyList SharePoint list and add a new item. Once the workflow has run and completed, navigate to the workflow history list, and verify that the string SharePoint2013listsandlibraries was written to the history list.