Normally I would recommend against attaching files to a List Item as these files are NOT indexed by SharePoint Search, and if you really need to combine a List and a number of files, I would strongly recommend that you have a look at Document Sets. Yes, I know that Microsoft is treating Document Sets as a red-headed stepchild, aka have forgotten that they exist, but for certain scenarios they are still the best choice.
In this case the List already exists, and the files are not that important. However, the customer required that I investigated whether we could integrate the files into the existing Search driven portal.
Using my favorite search debugging tool, the Chrome extension SP Editor, I browsed through the existing managed properties, and found LinkOfficeChild:
When I checked the properties for LinkOfficeChild in the SharePoint Search schema it was pretty useless as it could neither be searched, queries or refined, so I mapped it to a RefinableString.
Setting up the search web part for the List Items is pretty straight forward:
The query is {searchTerms}
ListId:"a023b69c-4132-4ca6-bf63-1e7d5663f1c7"
where the ListId is pointing to my List.
Adding the RefinableString to the Selected Properties is required.
The Layout is this case is a Details List, and I have added two colums, ListItemId and LinkOfficeChild (using the RefinableString)
Once you are seeing data in the LinkOfficeChild column ( You have to wait for the Search index to connect the RefinableString with the Link.OfficeChild crawled property) then you are ready to continue.
Step two is to add another PnP Search Results web part that will display the files attached to the selected List Item:
So first enable Item selection in the List Items search web part.
Then switch to the "Attached Files" web part.
Add the RefinableString to Selected Properties, and make sure that ListItemId is selected as well.
Add a new Layout Slot for the RefinableString. In this case I names it AttachedFiles, and we are going to use it in our custom Layout
Switch to "page" 3 and connect this web part to the List Item search web part using the ListItemId as below
This allows us to use the ListItemId of the selected Item in the first web part as a query input:
Refinablestring119:"https://[yourTenant].sharepoint.com/sites/PnPModernSearch/Lists/Datalist/Attachments/{filters.ListItemId.valueAsText}/*"
So when I select a List Item with the ListItemId of 2, the resulting query will be
The final task is to make a custom layout for the files.
Select the List Layout on "page" two in the Attached Files search web part, and use "select results template" to replace the layout with the sample found at pnp-modern-search-layouts/Results/Handlebars/Attached file from a List Item/AttachedFilesFromListItem.md at main · microsoft-search/pnp-modern-search-layouts
The only part of the layout that is slightly tricky is this:
{{#each (split (slot item @root.slots.AttachedFiles) ";") as |file| }}
<div class="simpletags">
<span>
<pnp-iconfile class="icon" data-extension="{{slot item @root.slots.FileType}}" data-theme-variant="{{JSONstringify @root.theme}}"></pnp-iconfile>
<a href="{{trim file}}">{{#with (split file '/')}}{{[9]}}{{/with}}</a>
</span>
</div>
{{/each}}
The AttachedFiles property lists the file separated by a semicolon, so that part is easy, but getting the file name is trickier as my knowledge of Handlebars is rudimentary, and I sorely miss a SubString function. However, using another split and showing the content of index 9 works, as long as the URLs follow the expected pattern (no subsites, thank you).
Edited:12 Nov 24, the issue above has been solved using @last
{{#each (split (slot item @root.slots.AttachedFiles) ";") as |file| }}
<div class="simpletags">
{{#each (split (file) "/") as |segment| }}
{{#if @last}}
<span>
<pnp-iconfile class="icon" data-extension="{{slot item @root.slots.FileType}}" data-theme-variant="{{JSONstringify @root.theme}}"></pnp-iconfile>
<a href="{{trim file}} style="color: aliceblue;">{{segment}}</a>
</span>
{{/if}}
{{/each}}
</div>
{{/each}}
This is just one of the many scenarios where the "Master - Detail" pattern available when using two connected Results web parts, is super useful.
If you have other cases like this, the PnP Modern Search team would love to hear about it.
Comments