Wednesday, September 25, 2013

Alternative of "Loop" activity in Nintex Workflow

Recently i was asked to synchronize a SharePoint list with a third party system. The third party system exposes the data via web service and outputs the result in XML with pagination.

Well the requirement was very simple so i jumped on it using Loop activity to synchronize all the items from third party system to SharePoint list. But when i ran full test i found the workflow to be very slow and time consuming as Loop Activity waits for 5 minutes between iterations. so if you have to run a loop 100 times the workflow will run for approximately 500 mins and that's not nice.

So i looked for an alternative way of iteration and the only available activity is "For each" which accepts only collection variable. So how do we make use of For each instead of Loop activity.

In my case the data from XML gives me the total number of pages.

So lets take an example that we have to run a for each loop for 55 times. so we will create some workflow variables for this

Variable Name
Variable Type
NumberOfpages
Number
PaddedLeftStringWithDelimeter
Multiple Lines of Text
PaddedLeftString
Multiple Lines of Text
TempPaddedLeftStringCollection
Collection
TempPaddedLeftString
Single line of text
TempPaddedLeftStringCollectionIndex
Number
TempPaddedStringCount
Number

Lets Assume NumberOfPages=82

Our Workflow looks like this.I will cover each of the activity in detail



Build String


In this activity we are padding '-' symbol to 0 equal to NumberOfPages. The output of the string will be something like ----------------------------------------------------------------------------------0

Regular Expression (Format the Padded String)

In this activity we will replace the '-' with {ListItemId}; value. The output of this activity will be like 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0

Regular Expression (Split String)


Finally in this activity we will split the string with a separator ; and store it in collection variable

Collection Operation

This activity is just for testing purpose to get the count of the collection variable.

Once every activity is configured we can add a for each loop 



So we are ready to go and can easily replace Loop activity with the "ForEach" saving lot of time. Initially with Loop Activity my workflow was taking 410 minutes but now it completes in 1 hour and 40 mins approx.

Monday, August 19, 2013

Debugging in Nintex Workflow

We all know that Nintex provides an easy and user friendly way of creating and deploying workflows in a short span of time.

The Nintex workflow activities are pretty simple and straightforward and usually people do not end up in any big issues but believe me some times the Nintex workflow becomes a pain and does not provide any useful information about the issue.

In my experience I have ran into issues when working with workflow variables in collection and with complex business logic.

So what do we do when we have to debug the workflow with the tons of iterations and complex logic?

Well Nintex allows us to debug the workflow not as familiar VS IDE provides but very close to it. if you navigate to the Central Administration of SharePoint and then Nintex Workflow Management and then Global Settings you will find a section for "Verbose Logging"






When you enable the verbose logging for Nintex Workflow then Nintex stores lot of Information about workflows in Nintex Workflow database which can be used to debug the workflows. Remember to perform an iisreset after you change the "Verbose logging" to yes.

Now if you create a new or open an existing Nintex workflow and navigate to workflow settings you will see a new option in it.



To see it in action lets create a sample Nintex workflow with some collection variables with a Loop action. We will add value to a collection variable in loop and see how Nintex logs the debug information.



Once you run the workflow and go to Nintex workflow history by context menu you will find some additional details in "Workflow Information"







Now if you click on any of the Nintex workflow activity a pop up window will open where you can see the state of the workflow variable and other information as shown below.




You can also export the activity information into xml by using Export link on the top right of the pop up window.

The verbose logging puts lot of data in Nintex database hence try to keep the number of days to minimum for retaining verbose logs.

Friday, August 16, 2013

SharePoint isDlg querystring mystery

One of my client asked me to show the preview of SharePoint list item in a custom task form page.

So I thought of using an iframe in a custom task form using a webcontrol and passed the src attribute as

"src='http://sharepoint:784/Lists/TestNintex/DispForm.aspx?ID=3&IsDlg=0'"

As we did not want to have left navigation appear on the iframe i passed a query string as "isDlg=0" but to my surprise I was still seeing the left navigation.

I verified the piece of code again and again but could not find any thing.Also google did not help me.


Somehow I thought of changing the value of isDlg to 2 and to my surprise the list item page was rendered with no left navigation.


"src='http://sharepoint:784/Lists/TestNintex/DispForm.aspx?ID=3&IsDlg=2'"

I am not sure how Microsoft has implemented it but it works.

Happy Coding!! :)

Thursday, August 15, 2013

Nintex Forms with SPServices library

I have recently started playing with Nintex Forms 2010. The product from Nintex is really nice and provides us with lot of capabilities. However If we compare Nintex Forms with InfoPath forms the Nintex form still needs lot of improvements.

For example to call WebService or to retrieve data from a different system using web services the InfoPath form allows us to call webservice with filters by default. But in Nintex it is not provided by default so what do we do?


Well Nintex forms comes with a powerful script library "jQuery" which solves our problem.If we look at the future of SharePoint product the preferred way of developing any module is "SharePoint hosted" app making use of client side scripting so in my opinion the future of SharePoint customization relies on scripts only.


So considering the support of "jQuery" I started with "SPServices" library to call "UserProfile" Webservice but i keep on getting error "Object does not support this property or method". After looking at the jQuery implementation in Nintex Forms I found out that Nintex implements below line of code.

NWF$=jQuery.noConflict(true);

So what does the above line of code does? It actually flushes out all the previous instances of jQuery and stores it in NWF$ that means in Nintex forms we have to use "NWF$(document).ready(handler)" instead of "$(document).ready(handler)" to use the capabilities of jQuery.
So how do we use "SPServices" library with Nintex form?

If you look at the "SPServices" library you will see that it is encapsulated in "jQuery" anonymous function as

(function($) {  /*more code here*/  })(jQuery);

Which allows it to use $ inside all of the defined functions.

If you see the anonymous function above it needs a jQuery as a parameter.

So what can we do to make "SPServices" work with "jQuery" ? Well we can update the parameter of jQuery anonymous function with NWF$ as shown below to pass the current jQuery variable.

(function ($) {


})(NWF$);


Update the "SPServices" library and provide its reference in Nintex Forms. To Call "UserProfile" service using jQuery you can write a below method to get the data.

function getUserProfile(adLogin) {
    if (adLogin == '' || adLogin == null) {
        alert('empty value')
    }
    var profile = {};
    NWF$().SPServices({
        operation: "GetUserProfileByName",
        async: false,
        AccountName: adLogin,
        completefunc: function (data, status) {
            NWF$(data.responseText).find("PropertyData").each(function (idx, val) {
                var $val = NWF$(val);
                var name = $val.find("Name").text();
                var value = $val.find("Value").text();
                profile[name] = value;
            });
        }
    });
    return profile;
}

Once everything is done you can see the results in Nintex Forms as below.