Wednesday, June 26, 2013

SharePoint 2013 Workflows and Lookup Columns

I may have run into a bug with SharePoint 2013 workflows and lists with lookup fields, although I've not seen it reported elsewhere.

THE STORY
I was building a workflow that ran on a list with a lookup field ("Workflow List"). That value came from a second list ("Lookup List A"). I needed to use the value set for that lookup field to pull additional information from a third list ("Lookup List B").

Workflow List Lookup List A Lookup List B
Title Department Department
Body Sub-department Department ID
Department Additional info Department email


THE ISSUE

In SharePoint 2010, it was possible to perform this sort of data relationship, as long as you specified that you were passing the value as a "lookup value". In 2013, I found that the field was set to that by default (and the option to change the datatype disabled), and the workflow would throw odd errors indicating that it couldn't find the lookup value requested. In fact, it was often reporting that it was looking for a list with a GUID made of nothing but zeros, which obviously didn't work.

I tried all kinds of combinations of lookup fields, created sample lists and added fields with different types and values to ensure it wasn't just a corrupt list, and nothing worked. It seemed my workflow just couldn't figure out lookup columns.

THE SOLUTION

Since the workflow just doesn't get lookup fields, let's give it something static to work with instead. If we can capture the ID of the lookup field and store that as a static value in our list, the workflow can happily use that to look up our related values.

THE CODE

First, edit your list to include an additional field that you can store your lookup ID in. In my case, I created DepartmentIDCopy, and made it a single-line text field (an integer would also work, and probably be more precise).

Then, edit your NewForm, EditForm, and/or any custom forms that a user could visit to change your lookup value. Just after the PlaceHolderMain tag, add the following JavaScript:



<script type="text/javascript"> 
  var sourceField;
  var targetField;

  function doFieldCopy() {
    targetField.val(sourceField.val());
    //alert('hi!');
  }
    
  //Copy selected department to text field for workflow manipulation
  $(document).ready(function() {
    sourceField = $("select[title='Question Department']");
    targetField = $("input[title='QuestionDeptCopy']");

    sourceField.change(function() {
      doFieldCopy();
    });

    doFieldCopy();
  });
</script>



This script will fire whenever the value in your lookup list drop-down is changed, so whatever the user selects should be recorded. It also fires when the page is loaded, to ensure that the value isn't accidentally dropped.

Thirdly, add an input field on your page for your new lookup ID storage field (I just created a new item form, copied the row from there, and pasted it into my existing forms). Set the display:none to ensure users don't accidentally manipulate the field.

Finally, update your workflow to use the new ID field, and voila - happy lookups!