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: 61% [?]

jQuery vs Webparts solution

Filed under:IT,SharePoint — posted by Jason MacKenzie on March 26, 2010 @ 6:05 pm

As I mentioned in my last post, I had to come up with a simple way of fetching an employee’s phone number and allowing them to update it through SharePoint. I contemplated developing a web part that would interact with the HR system but with the length of time a deployment can take I thought that it might be simpler to use jQuery. This way I don’t have to develop and deploy any custom .Net code. I simply have to write some HTML and jQuery and embed that into the page.

A few caveats. Security is not really an issue here. There is no requirement to ensure that people can only update their own phone number. Although since there is a mapping between a user’s AD account and their HR Employee ID that logic could easily be handled in the web services if required. The other is the fact that cross-domain scripting is not supported so your HTML page will need to be on the same server as the web services.

The last caveat is that the page is hideous and logic is sketchy – this was only a POC to demonstrate a different approach to tackling these types of problems.

How the page works is that a user loads the page and is presente d with a textbox and a button. They enter their Employee ID into the text box and click the button. This uses ajax to call a .Net ASMX web service called EmployeeInfo which accepts the Employee ID in the form an integer and returns an Employee object.  We then simply render that on the screen, hide that button and show another one.  The user can then enter a new phone number in the textbox, click the button which calls the UpdatedEmployee Web Service.  This web service accepts the Employee ID and Phone Number and returns a Response object that has a property called ResponseStatus which we can check in our client code.

This first thing if of course to add a reference to our jQuery library which is stored in a SharePoint library.

<script type=”text/javascript” src=”<url>/jquery-1.3.2.min.js”></script>

What follows is the HTML code which is simple – and hideous.

<div id="instructions">Enter Employee ID</div>
<div id="controls">
<input id="txtEmployeeID" type="text" />
<input type="button" value="Search" id="Button1" onclick="CallWebService('http://<url>/Service.asmx/EmployeeInfo', document.getElementById('txtEmployeeID').value, '')" />
<input type="button" value="Update Phone Number" id="btnUpdate" onclick="CallWebService('http://<url>/Service.asmx/UpdateEmployee', _employeeid, document.getElementById('txtEmployeeID').value, '')"
style="display:none;" />
</div>
<div id="loadingDiv" style="display:none"><img src="http://jaymoss/PublishingImages/ajax-loader.gif" /></div>
<div id="ResultSet"></div>

It’s very straightforward. A textbox to enter the Employee ID and a button to request the employee information. Another button to submit the phone number back for updating and a few DIV tags to control formatting.  You can see  in the onclick events of the buttons that we are calling the same Javascript function and passing in different parameters.  Below is the code that int.eracts with the .Net web services.

I don’t want to spend too much time on the simple logic so I’ll focus on the Ajax piece.  All you need to do is call the AJAX function and pass in the correct parameters.  The url parameter is the actual url of your web service.   The data is returned in JSON.  More information on decorating your web services to be compatible with this format is located here: http://stackoverflow.com/questions/211348/how-to-let-an-asmx-file-output-json.

var data;

function CallWebService(url, employeeid, phonenumber)

 if (phonenumber.length == 0)

 {

 data = “{‘employeeid’:'” + employeeid +”‘}”;

_employeeid = employeeid;

}

else

{

data = “{‘employeeid’:'” + employeeid + “‘, ‘phonenumber’: ‘”+ phonenumber +”‘}”;

$(‘#ResultSet’).attr(‘style’, ‘display:none’);

$(‘#loadingDiv’).attr(‘style’, ‘display:block’);

$(‘#controls’).attr(‘style’, ‘display:none’);

}

$.ajax({

type: “POST”,

url: url,

contentType: “application/json; charset=utf-8″,

data: data,

dataType: “json”,

success: success,

error: ajaxFailed

});

}

Since our web services accept parameters we pass them in the data parameter.  All you really need to know is that the format is {‘parameter’:'value’}.  Multiple parameters are separated by commas.  You can pass arrays as well which is well documented online.

The last two parameters are the function to be called if the call is successful and if it fails.  In our case the success function is creatively named “success” and the error function is called “ajaxFailed”  below are the functions themselves.

Side note:  I’m having a hard time concentrating on this post because I’m watching all the pre-fight hype of the GSP vs Dan Hardy fight.  This is going to be ugly.  Dan Hardy doesn’t have a prayer but I digress.  Update:  I can’t believe it went the distance.

function success(data, status)

{

hideLoader();

if (data.d['ResponseStatus'] == “Success!”)

{

alert(‘Employee Phone Number Successfully Updated’);

$(‘#controls’).attr(‘style’, ‘display:none’);

}

else

{

$(‘#ResultSet’).html(data.d['EmployeeName'] + ‘ <br> ‘ + data.d['PhoneNumber']);

$(‘#txtEmployeeID’).attr(‘value’, ”);

$(‘#Button1′).attr(‘style’, ‘display:none’);

$(‘#btnUpdate’).attr(‘style’, ‘display:block’);

}

}

function ajaxFailed(xmlRequest)

{

hideLoader();

alert(xmlRequest.status);

}

Data is the JSON object is returned where you can check the properties of the object returned by your web services.  Easy as pie!

Upload the HTML to the web server the web services reside on and you’re golden.  You can then use a simple Page Viewer Web Part to display your masterpiece inside SharePoint and your users will never be the wiser.

Obviously, there are many situations when a custom developed web part is required but my intention has been to demonstrate an alternative approach to accomplish a specific problem without writing custom .Net code.

Enjoy and all comments are always welcome!

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: 32% [?]

jQuery vs Webpart

Filed under:IT,SharePoint — posted by Jason MacKenzie on March 24, 2010 @ 4:13 pm

I was recently presented with the following issue. We need a web part that will allow someone to enter their employee id and update their phone number which will then be posted back to the HR system. Web part?? Come on!

This can be accomplished with jQuery, some nice HTML formatting and…..oh wait…that’s it.

Anyone that knows jQuery will know that there are cross-domain scripting issues that we have to deal with by design. So we may have “develop” and HTML page that uses jquery and ajax to do the calls and host it on the web server that serves up the required web services.

Code to follow but give me a break. You could do this in a traditional web part deployed as a feature and go through the entire SDLC or write some simple HTML and call the pre-existing services.

Code to follow.

Tell me I’m wrong please.

VN:F [1.9.3_1094]
Rating: 10.0/10 (2 votes cast)
VN:F [1.9.3_1094]
Rating: +3 (from 3 votes)

Popularity: 24% [?]

jQuery Blogging Part Deux

Filed under:IT,SharePoint — posted by Jason MacKenzie on January 28, 2010 @ 12:27 pm

This is a continuation of my previous post on enhancing the SharePoint Blog user interface with jQuery. In that sample I demonstrated how to use jQuery along with a customized Content Query Web Part in order to create a nice accordion effect for recent blog comments. In this example I will take things further and demonstrate:

  • How to include the most recent blog posts using jQuery to create a nice scrolling effect
  • Use the concepts introduced by Mark Miller for creating a Scripting Resource Center
  • How to change the look and feel of your jQuery components by using jQuery themes
  • Finally I will use the jQuery Dynamic List Filter and MOSS Filter web parts to create a dynamic page for searching posts and comments
  • I’ll also use the ChartPart web parts and some SPD workflows to create some graphs to visualize information about the blog

The completed blog home page looks like the image below. Please check the following screen cast to see it in action. Note that some of the more dynamic effects aren’t visible in the video due to the fact that Camtasia Studio seems to consume a lot of resources. You can see them in the video attached to the previous blog post. http://www.screencast.com/users/JasonMacKenzie/folders/Default/media/7e067f8b-af00-4a69-aae0-59c2fc41a198

Blog Scrolling

The first effect I wanted to achieve was to create a scrolling list of recent blog posts. In order to achieve this I used the Content Query Web Part along with the Scrollable plugin from jQuery Tools. The vertical scrolling requires the HTML to be output in the following structure:

<div id="actions">
<a class="prevPage">&laquo; Back</a>
<a class="nextPage">More pictures &raquo;</a>
</div>
<!-- root element for scrollable -->
<div class="scrollable vertical">
<!-- root element for the items -->
<div class="items">
<!-- first item. can contain anything -->
<div>
<!-- image -->
<img src="http://farm1.static.flickr.com/_m.jpg" />
<!-- title -->
<h3>1. Barcelona Pavilion</h3>
<!-- content -->
<p>
The Pavilion was not only a pioneer ...
</p>
</div>
<!-- second item (and so on) -->
<div>
...
</div>
</div>
</div>

So, as in the last post I’ll create a custom item template in ItemStyles.xsl in order to achieve this effect. I won’t go into to detail explaining this as y0u can read my previous post for the mechanics of it. I’ll post the template in it’s entirety for you to use:

<xsl:template name="ScrollableBlogPosts" match="Row[@Style='ScrollableBlogPosts']" mode="itemstyle">
<xsl:variable>
<xsl:call-template>
<xsl:with-param select="'ImageUrl'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable>
<xsl:call-template>
<xsl:with-param select="'LinkUrl'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable>
<xsl:call-template>
<xsl:with-param select="@Title"/>
<xsl:with-param select="'LinkUrl'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable>
<xsl:if test="@OpenInNewWindow = 'True'" >_blank</xsl:if>
</xsl:variable>
<xsl:if test="count(preceding-sibling::*)=0">
<div></div>
<style>
<xsl:text disable-output-escaping="yes"&gt
.vertical {position:relative; overflow:hidden; height: 665px; width: 650px; border-top:1px solid #ddd; }
.items {position:absolute; height:20000em; margin: 0px;}
.items div {margin:2px 0; padding:2px;}
.items img {float:left;margin-right:20px; height:180px; width:240px;}
.items h3 {margin:0 0 5px 0; font-size:16px;color:#456; font-weight:normal;}
#actions {width:100%px;margin:30px 0 10px 0;}
#actions a {font-size:11px; cursor:pointer; color:#666;}
#actions a:hover {text-decoration:underline;color:#000;}
.disabled {visibility:hidden;}
.nextPage {float:right;}
</xsl:text>
</style>
<div>
<a>Previous</a>
<a>More Blog Posts</a>
</div>
<a></a>
<xsl:text disable-output-escaping="yes">
<!-- root element for scrollable -->
&lt;div&gt;
<!-- root element for the items -->
&lt;div&gt;
</xsl:text>
</xsl:if>
<div><div><strong><a style="font-size:medium;color:gray" href="{$SafeLinkUrl}" target="{$LinkTarget}" title="{@LinkToolTip}">
<xsl:value-of select="@Title"></xsl:value-of></a></strong></div><xsl:value-of select="@Body" disable-output-escaping="yes"></xsl:value-of>
Posted at <xsl:value-of select="ddwrt:FormatDateTime(string(@PubDate) ,1033 ,'dd-MM-yyyy')" />
Posted By: <xsl:value-of select="@Author"></xsl:value-of> |
<a style="font-size:x-small;color:black" href="{$SafeLinkUrl}#Comments" target="{$LinkTarget}" title="{@LinkToolTip}">
Comments</a>
<hr style="color:white;border-bottom:1px solid black;"></hr>
</div>
<xsl:if test="count(following-sibling::*)=0">
<xsl:text disable-output-escaping="yes">
&lt;/div&gt;
&lt;/div&gt;
</xsl:text>
</xsl:if>
</xsl:template>

The next thing we’ll need to do is modify out CEWP to contain the jQuery to handle the scrolling. I will include all the script that is included in order to make our prototype function properly. The relevant script is in red. Note the easing function – for those that read my posts I’m sure you recognize that I did not come up with that on my own. All those algorithms are from the jQuery Easing plugin and you can simply copy and paste them in order to change the easing effect.

<script src="/sprc/Resources%20%20jQuery/jquery-1.3.2.min.js"></script>
<script src="/sprc/Resources%20%20jQuery/jquery.tools.min.js"></script>
<script src="/sprc/Resources%20%20jQuery/jquery-ui-1.7.1.min.js"></script>
<link rel="stylesheet" href="/sprc/Resources%20%20jQuery/jquery-ui-themes-1.7.1/excite-bike/jquery-ui.css">
<script>
$(document).ready(function(){
$("#accordion").accordion(
{ autoheight: false}
);
// initialize scrollable
$("div.scrollable").scrollable({
vertical:true, size: 1,easing: 'custom', speed: 1000
})
jQuery("#dialog").dialog({
bgiframe: true, autoOpen: false, modal: true, show: 'slide'
});
$("#demo img[title]").tooltip('#demotip');
});
// custom easing called "custom"
$.easing.custom = function (x, t, b, c, d) {
if (t==0) return b;
if (t==d) return b+c;
if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
}
function PopulateText(textToShow, title)
{
document.getElementById("dialog").innerHTML = textToShow;
document.getElementById("dialog").title = title;
}
</script>

Scripting Resource Center

Following Mark’s advice I created a Scripting Resource Center to centrally host all jQuery related files as well as a wiki for all things SharePoint. I have download the latest versions of jQuery – 1.2.6 +, recent versions of jQuery UI, jQuery Tools as well as all the jQuery UI themes:

Changing Look and Feel

jQuery themes make it extremely easy to change the look of your jQuery components. See the screencast for the specific look but in a nutshell all you need to do is change the theme name in your CEWP. I’m quite pleased with the fact that the theme that works for me is called excite-bike. For some reason the name makes me happy.

<link rel=”stylesheet” href=”/sprc/Resources%20%20jQuery/jquery-ui-themes-1.7.1/excite-bike/jquery-ui.css”> to
<link rel=”stylesheet” href=”/sprc/Resources%20%20jQuery/jquery-ui-themes-1.7.1/redmond/jquery-ui.css”>

Personalized View and Dynamic List Filtering

I added a page where a user can view all blog posts along with their own comments. This uses the Filter web parts that are part of MOSS Enterprise Edition. The important thing to note here is that you need to set the Select Value to Provide to SharePoint profile value for current name and then select “Name” from the drop down.

Adding dynamic filtering could not be easier thanks to Jaap Vossers solution. This requires jQuery 1.2.6 so I installed that into the Resource Center and then it’s just a matter of placing the script in a CEWP. In my view this dramatically improves the user experience.

Charting and Real-Time Data

For the last piece of the puzzle I want to provide some charts on the home page that would show in (near) real time some of the activity on the blog. For this I downloaded the ChartPart solution from CodePlex and begged my administrator to install it :) It is incredibly easy to configure and it renders really slick looking charts.

Everything else was accomplished with a few custom lists and a 2 step workflow called Activity Tracker on the Posts list.

I created 2 lists – Comment Counter and Post Comment Counter.

Comment Counter contains 3 columns – Title, Comment Poster (person) and Comment Count (number).

Post Comment Counter contains 2 columns – Post Subject and Comment Count (number).

Below is a shot of the workflow in SPD

Both steps are essentially the same and the process goes like this:

  1. If the current user has a an entry already in the Comment Count list then get the current comment count, increment the count by 1 and then update their list item.
  2. If the user has no item in the Comment Count list then create a new item for them with a Comment Count of 1.

The second step is essentially the same except we are looking to see if an item with the same subject as the current post the user is commenting on exists. If so increment by 1, otherwise create a new item for that Blog Post with a Comment Count of 1.

We can then create views and easily hook the charts up to those views.

And that is it. Going through this process has been extremely educational for me as it relates to integrating jQuery with SharePoint and I can say with certainty that our users are very impressed by the new pizazz we’re adding to their intranet. It also made it clear how many resources there are available and what you can do when you combine them into a holistic solution.

Please feel free to send me any comments or questions.

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

Popularity: 28% [?]

SP 2010 Install

Filed under:IT,SharePoint — posted by Jason MacKenzie on November 18, 2009 @ 7:45 am

I downloaded the SP2010 Beta from MSDN and was nearly overcome by geek euphoria.   I installed in on a clean 64 bit Windows 2008R2 Hyper-V instance.

The first issue I ran into was related to SQL Server 2008.  I had installed SP1 but I got prompted that I needed to install SQL Server 2008 SP 1 CU2.  I did that an proceeded to install SharePoint Foundation.

I then installed SharePoint 2010.  At some point I noticed a message related to the User Profile Application.  When the install completed I created the root site collection and was able to browse to it and Central Admin as expected.

My next step was to configure the user profile import from AD.  When I navigated to Central Admin> Application Management > Manage Service Applications  and clicked on the User Profile Service Application I was presented with the following error message: User Profile Application’s connection is currently not available. The Application Pool or User Profile Service may not have been started. Please contact your administrator”.

Some research pointed me to the following blog post fromTravis Neilson.  I followed those steps, reran the configuration wizard but no joy.  I was still in the same situation. I decided to delete and recreate the User Application Service Proxy.  

DeleteUserAppService

I then recreated the User Profile Service Application:

createNew

After selecting the menu item the following dialog appeared which is fairly straightforward to configure.

CreateNewOne

This seemed to resolve the issue and I was able to move on to the next steps.  I’m currently working on importing the user profiles from AD.  It’s not going well but I’ll post the issues and resolutions when I have resolved them.

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: 49% [?]

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% [?]

SP Workflow Governance

Filed under:IT,SharePoint — posted by Jason MacKenzie on October 13, 2009 @ 10:45 am

As the adoption of our MOSS 2007 platform continues to gain traction we have begun delivering some of the more important pieces of our moss_2007governance plan.  Due to our limited resources we have identified the areas that we feel are the most important and are delivering those as they are developed. 

First, a primer on our environment in order to provide some context on the why.  I work for a global manufacturing company with a decentralized operational structure.  We currently have about 8000 users and are at approximately 600,000 hits per month across the portal.  Many of our facilities are coming on board to our MOSS implementation which is managed centrally in the Toronto area by a relatively (by the standards of other organizations) small team of people.    When I say small – I mean 3 in IT.   As our facilities come on board there are increasing requests to automate business processes by creating and hosting workflows in SharePoint.  We felt it was necessary to quickly develop and publish some policies around this type of activity that takes into account three main factors:  reinforcing the concept of user ownership over SharePoint functionality, the resource levels at the central office, and the current processes around deployment that are already in place.

Obviously many pieces of successful governance are inter-related which is why in conjunction with these specific policies we have published governance about the roles & responsibilities of the various types of users interacting with SharePoint: site collection administrators, site administrators, content creators etc.  Support processes need to be documented as well in order for the site administrators/content creators to understand their role and the escalation path.

Below is an overview of the workflow-related policies and the rationale behind them.

Policies

  • Out of the Box SharePoint workflows will be the first option examined when implementing workflows
    • This is straightforward and doesn’t require much explanation.  OOTB should always be the first option when looking at new functionality whether its SharePoint or any other technology solution
  • We do not currently support the out of the box translation workflows
    • Our implementation is currently English only so there is no business need to be using these workflows
  • We will not provide support for user developed SharePoint Designer workflows
    • This does not mean that we will not allow SPD workflows to be created and deployed.  It means that should a user choose to use SPD designer to create a workflow they own it we will not be able to support them with their troubleshooting requirements.  We simply do not have the resources to spend time with individual users or teams analyzing why their workflow is not doing what they expected it to do.
  • SharePoint Designer training must be taken prior to creating workflows with this tool.
    • We will however recommend training providers that can provide the required training or will assist individuals or teams with the fundamentals of SPD workflows.  We are also developing training material that will be provided through the MS Productivity Hub which will allow them to access material on demand.
  • The creator of the workflow owns it and is responsible for any documentation/knowledge transfer.
    • This was touched on in Point 4 but it can’t be stressed enough.  As with any business solution the functional business owners are responsible for knowing, using and training on the functionality and business processes they own.  We are making a much more concerted effort as part of the governance process to define and communicate the responsibilities of the business owner/site administrator. 
    • Communicating the necessity of cross training to the owner as a risk mitigation strategy is essential in helping them understand their responsibility.
  • Errors with workflows will be investigated by the owner of the workflow by reviewing the workflow history.  If, after investigating, the error appears to be platform related an email will be sent to the helpdesk with detailed information about the error.
    • The intention here is to again ensure that IT and more specifically the Help Desk is not the first option when an issue with a workflow is discovered.
    • Training the users on the fundamentals of workflows, tasks, workflow history etc. will empower them to attempt to troubleshoot the issue and resolve it more quickly.
  • We will not support the developer training or deployment related to custom developed workflows in Visual Studio.  
    • VS workflows need to be deployed by someone with access to Central Administration
    • We have a rigid deployment process of one deployment to QA and Production per month.  We have 1 person responsible for doing this (along with many other tasks including non-SP related).   This means that a custom developed workflow change could potentially be facing a lag of 1 month prior to being deployed
    • The issue for us here is not the mechanics of deploying the workflows, but the inevitability of the software developers at our divisions creating more complex workflows over time with increased needs for changes, errors and “emergency” deployments putting our current deployment processes and policies at risk.
  • SharePoint workflows will not be used to automate business critical processes.
    • This policy is derivative of the previous points and realities of our environment.  As is common with most SharePoint deployments there is a tendency for people to think of SharePoint as the solution for everything.  We are attempting to place reasonable constraints on the use of the environment while working proactively with our users to identify alternatives by helping them clearly define their requirement and choosing the right solution.

This policies will evolve over time, as they should.  We have already referred numerous people to these policies and their supporting documentation.  As our organizational maturity with this platform improves our governance model will evolve in parallel.

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

Popularity: 15% [?]

MS Tech Days Canada Review

Filed under:Conferences,IT,SharePoint — posted by Jason MacKenzie on September 30, 2009 @ 6:05 pm

techdays-2009I attended the Tech Days event in Toronto this week and wanted to share my thoughts on the Communication and Collaboration track.  This track was focused on SharePoint during day one.

This was my first time attending this event and I was fairly disappointed with it.  This is not to say that I didn’t get any value from it – I did.  But MS tried to do to much in too short a time with too diverse an audience.  The intial informal survey of the audience indicated that there was a mix between SharePoint Admins, developers, those who had little experience with the platform and those that weren’t running it and wanted to learn more.

The initial session was titled Deploying MOSS in a virtualized world.  The speaker was very knowledgable.  The topics covered ranged from SharePoint topologies,  server relationships and roles, interesting facts on the mechanics of search indexing and querying, options for installing SharePoint, application log errors, information SQL Server aliasing, backup and DR options as well as some information about Hyper-V virtualization.  All this in an hour and a half!  Regardless, I talked to the presenter afterwards and got some excellent information about the mechanics of search indexing and moving your query services to your WFE.  This is something I have been considering for some time.

The next session was held by Eli Robillard, a long time SharePoint MVP that I have worked with in the past.  His level of knowledge is quite frankly incredible.  He spoke about versioning  and upgrade of SharePoint based solutions.  It was interesting but very, very detailed but I wasn’t clear on why it was not part of a development related track.  For the non-developer audience, which was most of the room, he might as well have been speaking Mandarin.  This is no way a knock on Eli, he is a wonderful presenter. 

The following session was Comprehensive Security for MOSS 2007.  This was interesting but the coverage was too broad in my view.  There was good information about service accounts, permission levels, zones, authentication providers, FBA etc.  I found this quite useful.  The presenter then moved into standard SharePoint security.  I couldn’t quite grasp how someone that didn’t understand SharePoint OOB security would possibly benefit from a presentation the more administrative and technical aspects of security required to run the MOSS platform.

So overall I was disappointed but did come away with some information that I can use.  My advice to Microsoft is firstly to narrow the focus of the presentations.  Cover fewer topics more effectively.  Making the registration process more proactive in understanding the audience would be useful as well.  Personally I don’t think taking a show of hands to see who is a SharePoint admin at the beginning of the day is the appropriate time to get an understanding of your audience.

Will I go next year?  No.  However I’m glad I experienced it this year.   By the way – the breakfast was great, the lunch was awful.

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

Popularity: 5% [?]

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% [?]

Rolling Up Blog Posts

Filed under:IT,SharePoint — posted by Jason MacKenzie on September 2, 2009 @ 5:40 pm

I was recently presented with the following scenario:  As part of the creation of a SharePoint dashboard, my business users are interested in seeing the number of blog comments and their current status by blog.

Our blogs are contained as subsites of a site called Blog Central which reside in a site collection called “Public.”  The dashboard resides in a separate site collection.  Our site collections contain individual content databases.

As a former developer, my initial response is to find an out of the box solution wherever possible. 

  1. A content query web part wouldn’t suffice as its scope is limited to the current site collection
  2. Adding a new data connection in SP Designer to hook up to a dataview web part (DVWP) won’t work because the lists and libraries (not the web services) are also limited to the current site collection. These can be combined to recursively roll up content in the current site collection however.

I ended up querying the content database directly and presenting that through the DVWP.  So, in SP Designer I created a new Database Connection.  Database_Connections

 

 

 

 

Browsing to the content database for the Public site collection I wrote the following query in order to retrieve the correct data:

SELECT     Webs.Title,
                    CASE UserData.tp_ModerationStatus
                                   WHEN 0 THEN ‘Approved’ 
                                   WHEN 1 THEN ‘Rejected’ 
                                    WHEN 2 THEN ‘Pending’
                     END AS Status,                        
                      COUNT(*) AS Total 

FROM       AllLists INNER JOIN                       
                    Webs ON AllLists.tp_WebId = Webs.Id INNER JOIN 
                     UserData ON AllLists.tp_ID = UserData.tp_ListId 

WHERE     (AllLists.tp_Title = ‘comments’) AND
                      (Webs.FullUrl LIKE ‘%blogcentral%’) 

GROUP BY UserData.tp_ModerationStatus, Webs.Title 

ORDER BY Webs.Title, UserData.tp_ModerationStatus

I then conditionally formatted the DVWP to show different colours based on status and done.  
DVWP

 

 

 

If there is a better way to do this, using CAML or some other method,  please let me know and I will share it.

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

Popularity: 4% [?]


next page


image: detail of installation by Bronwyn Lace