I've wanted to blog this for a bit, but it finally reached a tipping point this week when I saw that two posts on the forum and an email in my inbox all needed a hand with the same subject.
You can't work with InfoPath and SharePoint for long before you find that some SharePoint Lists web service methods just don't play fair with InfoPath data connections (yeah, GetListItems, I'm talking to you). But don't let one or two bad apples spoil your barrel, because some of those web service methods work wonderfully with InfoPath. And that is what this post is about, leveraging some of the yummy good methods, and ignoring the bad.
So, you know how when you open a form in client from SharePoint, and someone else has it open, you get a little message letting you know and offering to open a read only copy? But no such love for browser forms.... Imagine, what if your browser form checked itself out with no effort on your user's part at all? And then, when they submitted, it checked itself back in?
This is no early winter pipe dream. You can do this with the above-mentioned IP-friendly web services. Before we dive in, I should mention I'm leveraging some functionality that is only available in SharePoint 2010 (and only seems to work correctly in forms opened in the browser) to find out if the form is already checked out (I underline this so you don't walk all the way through this and then fuss about your version of SharePoint being the wrong one or wonder why it doesn't work in client). I'm sure there are ways to do this in 2007, or in client, so don't let that stop you from giving this a try, but I did want to warn you upfront that your path may be different. Or bumpy.
Check Out Data Connection
In your form, add a receive data connection to the Lists web service for your SharePoint server (http://server/_vti_bin/Lists.asmx with server replaced with your actual server name). If in doubt, test your URL in your web browser -- you expect to see a page like this:
Lots of stuff to check out there, but we need to focus. So, back to your form. Receive connection:
Location of the service:
Select the CheckOutFile operation:
Note the parameters, but don't bother your purty head filling them out:
Ignore the next dialog, and in the final window, de-select the annoying checkbox that ALWAYS wants to get your data on load:
Check In Data Connection
Do everything you did in the section above a second time, with the following exception: select the CheckInFile operation:
You should now have two data connections in your form:
Form Library Data Connection
Create a data connection to the form library the form will submit to. In my case, since I am working with a brand new form, I need to publish my form and create my library. Your form may already be published. This article has more info on how to do this. Be sure you are either using a form field for the form name, or some unchanging piece of data you can get again, as you will need to know the form's name to check it in or out.
After your form is published to a library, create another data connection. This one will also be a receive connection, but this time to a SharePoint List or Library:
Use the URL for the server your form is published to, and select the library the form is published to... Here is the super important bit... select the checkboxes circled in red below:
Make sure you've included the field with info as to who the form is checked out to and indicate you only want data for this form. In this instance, get the data on load -- it will only be a single row.
Make the Magic Happen!
Form Load Rules
Our "Check Out" functionality gets added to the form load rules. Our first rule needs to make sure the form is not already checked out, so it will have a condition that the form is not currently checked out to anyone. Remember, the data connection to the form library is querying on form load, so it will tell us if our form is already checked out:
What you decide to do at this point is up to you -- you may wish to switch to a read only view or you may have a form field for user messages in your form. But regardless of the action for this rule, you need to make sure you've selected to not run any aditional rules if this condition is met:
For your second rule, you'll need to have a condition so that the check out rules only run if the form has been submitted to the library. One way to do this would be to see if the Checked_Out_To field is present:
For your actions, you are going to set the values for the CheckOutFile data connection, then query using that connection. The first parameter is pageUrl:
and it needs to be set to the URL of your form's XML file. You'll probably need to use a concat formula to create the full URL to the XML file:
In the screen shot above, the Title attribute is a field in my form where I am storing the name of the form.
Next, set the value for checkoutToLocal. Here is where MSDN is just invaluable. Let's go see what the options are for that bad boy, shall we?
Given this info, we'll set that field to true:
Having checked MSDN, we know that we can leave the final parameter blank. Our final action for this rule will be to query using a data connection -- the CheckOutFile data connection:
You can add another rule if you like that leverages the CheckOutFileResult and provide your user with information on how to proceed if the result is false for some reason.
Form Submit Rules
You probably already have all kinds of submit stuff happening in your form -- it must at least submit to a SharePoint library, or you would have had no interest in this post and would never have gotten this far. You need your form to be submitting via rules to add this new functionality to check the form in, however. If you haven't already got your form set up that way, modify the submit options. Here's some details -- I'll wait while you fix that.
We need to add to our submit rules -- we have to set the parameters for the CheckInFile data connection, and then we need to execute the query.
First, we set the pageUrl. This should be familiar to you, as we just did this in our form load rules.
Set the comment as you see fit -- it might be nice to set it something like "Auto check out and in from form" so that when someone reviews the history it is clear what was going on.
And, for the CheckinType, back to MSDN:
I'll not pretend I know what the difference is between a "minor" or "major" checkin. I imagine "overwrite" does what it says on the box. At any rate, set that field to 0, 1, or 2
Finally, add an action to run your CheckInFile query. As with checking out, you can check the CheckInFileResult and handle any errors if desired. Publish your form again, make sure your form library is set to always open in the browser, and sit back and relax while your users shower you with accolades.
EDIT: The awesome SharePoint guru, InfoPath MVP & all around good guy Clayton Cobb filled me in on the different checkin types. He says:
those values are referring to minor and major drafts like 1.1, 1.2, 1.3 (minor) and 1.0, 2.0, 3.0 major). First, versioning needs to be turned on, and then it needs to be set to minor or major for these to be in sync.
EDIT The Second: Who loves you? Qdabra loves you.... and we now have an XTP with this functionality that will make it even easier for you to implement this functionality in your form!