4 Clicks or 1? Using jQuery to Start a SharePoint Workflow.

Filed under:IT,SharePoint — posted by Jason MacKenzie on April 19, 2010 @ 1:57 am

The IT Urgent Change process needs to be automated.  It’s relatively simple and after gathering the requirements its clear that this can be accomplished using SharePoint and a SharePoint Designer workflow.  The workflow is created and published to the list.  The decision is made that the workflow will be started manually as opposed to automatically when the Change Request is created.  Everyone in IT has contribute access to the list and there are no security requirements related to who can or can’t start a workflow.

This means a user must take the following steps to initiate the workflow:

1. Click the context menu and click the Workflows menu item

2. Select the Change Process Workflow.

3. Initiate the Workflow

That’s a few more clicks than should be required so I wanted to find a way to make starting a workflow a one-click affair.  I knew this should be relatively simple with jQuery and the Dataview Web Part so I’d like to detail how I accomplished this so others can hopefully benefit from it.

The end result looks like this:

When the user clicks the Start Workflow link they see a nice Ajax loading image as seen below:

When the workflow has been initiated they are presented with a confirmation message telling them the process is underway:

On to the solution!  First I need to give a shout out to Marc Anderson , the creator of the jQuery Library for SharePoint Web Services which can be found here: http://spservices.codeplex.com/.  This is such a handy tool for interacting with the SharePoint web services from the client and this was my first opportunity to use it.  I simply downloaded the JS files and put them in my SharePoint Scripting Resource Centre site collection as first conceived by Mark Miller at EndUserSharePoint.com.  The original post can be found here: http://www.endusersharepoint.com/2010/01/05/build-a-sharepoint-scripting-resource-center/

Once that was done I need to do a few things.  I created a Web Part Page and opened SharePoint Designer.  I then added the Change Request list to one of the web part zones.  In order to get the customizations that wanted needed to create a DataView out of it so I simply right clicked on the list and converted it to a XSLT Dataview.   That’s all I really need to do here so I saved the page and opened it up in the browser.  What you can do with a dataview is almost limitless.  The best way to tackle customizations is to make all the changes you can using the SPD interface.  Once you have reached the limits of what you can do there you can start customizing the XSL.  Refer to the following series by Marc to learn everything you need to know about XSL and the DVWP.  http://www.endusersharepoint.com/2010/01/19/unlocking-the-mysteries-of-data-view-web-part-xsl-tags-part-1-overview/

When you modify a dataview in the browser you have a different set of options then when you work with a regular list.  The important thing we want to do here is modify the XSL in order to achieve the look and functionality we want.

In the interests of saving my sanity I copied the XSL and pasted it into SharePoint Designer (just a new XML document) so I could at least have the benefit of some colour in my life.  I added the following snippet  which I’ll explain as I go.

<xsl:if test=”not(normalize-space(@ChangePr) = ’5′ or normalize-space(@ChangePr) = ’2′)”>

<div>

<xsl:attribute name=”id”>

<xsl:text>WorkflowDiv</xsl:text>

<xsl:value-of select=”@ID” disable-output-escaping=”yes”/>

</xsl:attribute>

<a href=”#”>

<xsl:attribute name=”onclick”>

<xsl:text>javascript:StartWorkflow(‘</xsl:text>

<xsl:value-of select=”@EncodedAbsUrl” disable-output-escaping=”yes”/>

<xsl:text>’,'</xsl:text>

<xsl:value-of select=”@ID” disable-output-escaping=”yes”/>

<xsl:text>’);</xsl:text>

</xsl:attribute>

Start Workflow</a>

<img style=”visibility:hidden” src=”http://employeeportal/sites/sprc/PublishingImages/ajax-loader.gif”>

<xsl:attribute name=”id”>

<xsl:text>Loader</xsl:text>

<xsl:value-of select=”@ID” disable-output-escaping=”yes”/>

</xsl:attribute>

</img></div>

</xsl:if>

The result I want to achieve with this is another column in the dataview with the “Start Workflow” link that will call a Javascript function and passes in a few parameters and uses the jQuery Library for SP Web Services to kick off the workflow.

The following section says that we’re only going to render the link when the workflow is not complete or cancelled.  When you covert a list view to a dataview your workflow column which normally reads “In Progress’, “Completed” etc. switches to the numerical value.  Why?  I haven’t a clue.  But the easiest way is to use SPD to create some conditional formatting and then just copy the XSL that is generated.

<xsl:if test=”not(normalize-space(@ChangePr) = ’5′ or normalize-space(@ChangePr) = ’2′)”>

You can see that the 2 values we pass to our StartWorkflow function are the EncodedAbsUrl and the ID of the list item in question.  The EncodedAbsUrl for a list item looks like this: http://servername/sites/its/Lists/Change%20Request/107_.000.   We also output a hidden image with our nice loading image downloaded from http://www.ajaxload.info that will appear beside each item while the workflow is initiating.

Also note that our loading image and the div that wraps everything have an id property that concatenates on the list item id to it that we’ll use in our client side script.

On to the jQuery.   We need to add a Content Editor Web Part to our page and place the following script inside:

Our jQuery and jQuery Web Services references

<script type=”text/javascript” src=”/sites//sprc/Resources%20%20jQuery/jquery-1.3.2.min.js”></script>

<script  type=”text/javascript” src=” /sites/sprc/Resources%20%20jQuery/jQuery%20SP%20Services/jquery.SPServices-0.5.4.min.js”></script>

<script type=”text/javascript”>

function StartWorkflow(ItemURL, ItemID)

{

var loadingImage = ‘Loader’ + ItemID

var workflowDiv = ‘WorkflowDiv’ + ItemID

//Show our loading image

document.getElementById(loadingImage).style.visibility = ‘visible’;

$().SPServices({

operation: “StartWorkflow”,

item: ItemURL,

templateId: “{04ee1c93-f6b7-49b3-a79c-fa3142ecd688}”,

workflowParameters: “<root />”,

completefunc: function() {

document.getElementById(workflowDiv).innerHTML = ‘Workflow Started’;

}

});

}

</script>
As you can see there is very little scripting required here.  We take the URL of the list item and the item id.  We then show the loading image and make the web service call through Marc’s library:

There are 4 parameters.

  1. The operation is “Start Workflow”
  2. The URL is the value of the EncodedAbsUrl for the list item mentioned earlier.

The template id is the guid of the workflow template that we created in SharePoint Designer.  You can find this out by following the first 2 steps at the very beginning of this article and then copying the URL from your browser.  It will look something like this: http://servername/sites/its/Workflows/Change%20Process/Change%20Proce.aspx?List=d0fa2d98-6086-4c97-be85-4746c801e7f3&ID=89&TemplateID={04ee1c93-f6b7-49b3-a79c-fa3142ecd688}&Source=http%3A%2F%2Femployeeportal%2Fsites%2Fits%2FLists%2FChange%2520Request%2FAllItems%2Easpx.  You can see that there is a TemplateID value in the query string and that’s what we want

  1. Our workflow doesn’t have an initiation screen so we simply pass it an XML node.  You have to do this or the workflow will throw an exception.  This took some digging to find out why the workflow wouldn’t start.
  2. completefunc – what we want to happen when we’re done.  In this case we just want to get rid of the image and let the user know the workflow started.  Remember that AJAX is asynchronous so if you try to take post-initiation actions with code inline it will actually run prior to the workflow having been started.  If you want something to happen after the call to the SPServices library is done, put it in the completefunc.

There is no error handling in this solution yet but if you go to Marc’s Codeplex site you can see methods on how you can have error information returned and then trap them. It’s pretty straightforward.

That is how I used, jQuery, the jQuery Library for SharePoint Web Services and the DataView Web Part to allow a workflow to be started with one click.

VN:F [1.9.3_1094]
Rating: 10.0/10 (1 vote cast)
VN:F [1.9.3_1094]
Rating: +1 (from 1 vote)

Popularity: 59% [?]

SharePoint Workflows & Collecting Data from Users

Filed under:IT,SharePoint — posted by Jason MacKenzie on October 30, 2009 @ 5:39 am

Recently I was presented with a problem that I’m sure many of you have faced but it took some thinking – not an easy task for me – on the best way to resolve it. Let me give you a run down on the problem and then speak about the solution in more generic terms.

We have a list that is used to store various types of equipment that is available throughout our organization. We have a parent content type of Equipment Item and about 18 child content types including Robot, Welding, Plant Equipment etc. When equipment is identified and agreed to it is entered into this SharePoint List which initiates a SharePoint Designer(SPD) workflow. There are a few steps and then a Collect Data from a User action is called. This action creates a task for the specified user which in our case is where they specify the status of the equipment. With me so far?

Collect_Data

Here is the problem. There are currently approximately 300 active workflows and the volume of activity is going to increase significantly over the next few months.  The Collect Data from a User action however creates a task with a generic title and description like so:

Tasks

You can see what the issue is – how do I quickly tell which task is  associated with which piece of equipment?   You could click on the Link column to see the item however that is time cosuming and very cumbersome.  What we need to do is pull some key data from the equipment list into the associated task.    What makes a little trickier than it appears at first blush is the fact that until the user provides the required data to the workflow the Collect Data from a User essentially pauses the workflow.  This means that we can’t add a step in the workflow to update the task with pertinent information until after the user acts on it which is after he needs the pertinent information.  

The solution in this case is to create a secondary workflow on the task list that will be automatically triggered when a new item is created.  This workflow will then go back to the related item in the equipment list and pull in the required information.  We will use the Update List Item action in order to accomplish this.

Workflow_Designer

In this case we are updating 3 columns from the Equipment list but in the interest of keeping things concise we’ll focus on 1.  Since the workflow is being initiated on the Task list will will want to be updating the current list item.   We’ll be updating the SubCategory field, which is a column that we added to the Task list with the value of the Sub Category column from the Equipment list.

Update_List_Item

Defining the workflow look up is the key to making this work.  We know that these tasks must be associated with the specific Equipment item but how can we make sure we are looking up the values from the right piece of equipment?  Each list by default has a unique identifier called ID.  The task list also has a column called Workflow Item ID which is the ID of the related list item.  So by looking up the ID of the piece of Equipment that corresponds with the value of the Workflow Item ID in the Task list we will be able to grab the correct data to populate our Task list.

Define_Workflow_Lookup

I hope you found this information helpful and any feedback is welcome.

VN:F [1.9.3_1094]
Rating: 9.5/10 (2 votes cast)
VN:F [1.9.3_1094]
Rating: +1 (from 1 vote)

Popularity: 42% [?]

A Brutal Flaw with SP Workflows

Filed under:IT,SharePoint — posted by Jason MacKenzie on September 27, 2009 @ 3:58 pm

sad-face-1Everyone with an intermediate level of knowledge with SharePoint knows that there are 3 ways to create workflows that act on SharePoint lists/libraries.  In ascending order of complexity and flexibility they are:  OOTB SharePoint workflows, SharePoint designer workflows and custom developed Visual Studio workflows.

Imagine the folllowing scenario with which I have been faced.  Working with a user to implement a mission-critical business process that is focused on the steps required to acknoweldge and act on changes to customer requirements.  The workflow is developed, tested and rolled out – in production.  Everyone is happy.

A few months later a request for a change to the process is made which necessitates a change to the workflow that has 50 workflows currently in process.  How do we test that exactly?  Good question and there is no easy answer.

Since a SharePoint workflow is associated with a list based on a GUID that is environment specific you can’t do it without some ridiculous (in my view) manual steps that are outlined very nicely at my favourite SharePoint site – End User SharePoint.  http://www.endusersharepoint.com/2008/12/08/why-can%e2%80%99t-i-easily-port-sharepoint-designer-workflow-solutions-from-one-list-to-another-part-1/

In my view this is a deal-breaker for using SP workflow for automating business critical processes.  I’ll be attending the SP 2009 conference next month and will be eager to see if and how this has been addressed.  In the meantime if anyone has any experience with dealing with this issue I’m interested in hearing your feedback.

VN:F [1.9.3_1094]
Rating: 10.0/10 (1 vote cast)
VN:F [1.9.3_1094]
Rating: +1 (from 1 vote)

Popularity: 8% [?]

SharePoint Designer & Page Layouts – Headache Avoidance

Filed under:SharePoint — posted by Jason MacKenzie on July 29, 2009 @ 6:08 am

When creating a new Page Layout for a MOSS 2007 publishing site recently I stumbled across an interesting phenomenon that I thought I would share in with the intention of saving others some grief.

This thread will preface a more in depth analysis of the MOSS 2007 Publishing Infrastructure which will be coming in the near future.  Back to the issue at hand….

I created a new page layout in SharePoint Designer with the intention of using it as the Welcome page for my site.   As I was configuring the web parts on the page through the SharePoint UI, I made a slight modification to the page layout and saved it.  I refreshed the page in the browser and all the web parts that I had placed on the page had disappeared.   Perplexed (which is my typical state of mind), I took at look at the web part maintenance page (~URL/page.aspx?contents=1)  and discovered that all the web parts were present on the page but were not in use.  Placing the page in edit mode indicated that there were no web parts on the page.  I deleted the web parts from the web parts maintenance page.

When readding the web parts and publishing the page I asked the user to log in to verify the page was inline with her expectations and she reported the following error which I was not receiving. 

Error_Message

To make a long story longer it turned out the issue was in fact that I had not identified the id property of the web part zones in SP Designer.  SP Designer assigned an id to them as indicated in the image below. 
SP_Designer

I believe what was happening is that the id’s were being recreated when saving the page thereby resulting in the web parts being assigned to zones that no longer “existed”.  The solution turned out to be as simple as creating a new page layout and assigning a distinct id’s for each.

VN:F [1.9.3_1094]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.3_1094]
Rating: 0 (from 0 votes)

Popularity: 63% [?]



image: detail of installation by Bronwyn Lace