Thursday, December 14, 2017

List all Files & Folders for External Users (and Internal Users too)

This happens regularly with external users, and sometimes with internal users:  Someone shares a document or a folder with you, and you receive an email link to that item, and unless you bookmark that location, you're constantly referring to the email for the link.  Now when you're shared many files and folders, this can quickly get out of hand.

So a quick solution for this is to make a page that users can go to, that will display all of the folders and documents they have access to, like below:

This is just a page with two Search Content web parts, and a new Display Template.  For the Display Template:

  • First make a copy of the Item_TwoLines.html file on the site collection you're in, and name it something else, e.g. Item_UserAccess.html.
  • Change the title to "User Acces":  
<title>User Access</title>
  • Replace the mso:ManagedPropertyMapping line with the following:
<mso:ManagedPropertyMapping msdt:dt="string">&#39;Link URL&#39;{Link URL}:&#39;Path&#39;,&#39;Line 1&#39;{Line 1}:&#39;Title&#39;,&#39;Line 2&#39;{Line 2}:&#39;Title&#39;</mso:ManagedPropertyMapping>

  • You can then update the content in the display template by replacing the cbs-item div with the following:

        <div class="cbs-Item" id="_#= containerId =#_" data-displaytemplate="Item2Lines">
            <div class="cbs-Detail" id="_#= dataContainerId =#_">
                <h3>_#= line1 =#_</h3>
                <div class="cbs-Line2 ms-noWrap" title="_#= $htmlEncode(line2.defaultValueRenderer(line2)) =#_" id="_#= line2Id =#_">
                 <a class="cbs-Line1Link ms-noWrap ms-displayBlock" href="_#= linkURL =#_" title="_#= $htmlEncode(line1.defaultValueRenderer(line1)) =#_" id="_#= line1LinkId =#_">_#= line2 =#_</a>

  • Once these changes are made, save your file.
  • Then go to Site Settings -> Master pages and page layouts -> Display Templates -> Content Web Parts -> Item_UserAccess.html and select "Publish a Major Version"

Next, add a Search Content web part, change the query text to:

For Folders
Path:"" -Path:"" ContentTypeId:0x0120* -ProgID:OneNote.Notebook    -ContentTypeId:0x012002* -ContentTypeId:0x012000C0* -ContentTypeId:0x0120001928*

Where the ContentIDs above are bringing back folders, excluding OneNote Notebooks and MicroFeed folders.  And we're excluding SiteAssets which generally most everyone has access to.

For Documents
Path:"" -Path:""  ContentTypeId:0x010100*

Next update the items to show, change the Display Template to "List with Paging" and your new display template "User Acces":

And that should be it!

Thursday, December 7, 2017

SharePoint Designer Workflow suspended when you have a blank lookup field

I've noticed an issue when you're using a SharePoint Designer workflow, and you use the Current Item:LookupField in a task or an email, and that lookup value is blank, and you're setting it to use Lookup Values, Comma Delimited

You'll get an error of something like: 

System.InvalidOperationException: Values must be bound to a non-null expression before ForEach activity 'ForEach<DynamicValue>' can be used.

If you set it as a string, you'll see the JSON that's coming back, and for empty values it returns the string: 


Since Designer can't seem to handle that null object, for any lookup values you can do the following:

1)  Save the value as type String
2)  Test for the empty/null case by testing for the {"results":null} string
3)  Then set the value accordingly

So in my case, I've setup my lookup values as such: 

Where in Step 1 I'm using Current Item:Site Access As String, and inside the if statement I'm using the Current Item:Site Access as Lookup Values, Comma Delimited.