A while back I wrote this blog about copying attachments from a list item to a document library.
Well times have moved on and technologies change. I'm currently learning my way around O365 and of course Nintex Workflow and Forms for the platform.
My requirement this time was similar, but with a twist.
I'm creating a Mobile App that will allow frontline users to go out to sites and fill in inspection forms. The customer is keen for these inspections to be visually orientated so therefore they're going to be taking pictures on tablets to provide evidence that a section has met standards. At least 1 photo needs to be taken for each section. A section is going to be a particular area of the store (Front of House, store room etc). We then need to be able to easily identify section the photo was taken via metadata.
To achieve this we created our form with an attachment control for each section. This gives the user a nice easy way to associate the pictures with a certain section, and crucially it allows us to name each of the attachment controls.
Also, I needed to allow for the fact that they may not upload a photo for every section.
Kudos go to Marian Hatala for helping with the next bit. He suggested using the FormData XML to identify each of the attachment controls, and each of those attachment controls contained the filename of the picture that had been taken with it.
So my first job is to identify each of the sections. I create a 2nd list with an item for each of the sections in the form, I then query that list and store the results in a collection.
I then use a For Each action to iterate through each of the items in that collection. This provides me with the element I'm going to be looking for in the FormData XML so it needs to be spelt exactly the same as the Name of the attachment control on the form
My Query XML action looks a little like this
Here I am querying the NFFormData Item Property and my XPath query simply looks inside the FormVariables element for the name of the attachment control. Because there can be more than 1 picture in each attachment control, the result is stored in a collection, which I will break out using the following Regex actions. I'm no expert in Regex, so happy to be told if there is a better way of doing this.
Step 1 - 1" this removes the leading square bracket from the array
Step 2 - ;"] this removes the trailing square bracket from the array
Step 3 - Use the Split function in Regex to split the array by semi-colons
The reason this is required, is that this is the output of our array
p"IMG_20170614_164431_008.jpg;IMG_20170614_164433_045.jpg;"]
But this is the output of our collection after our Split function
/"IMG_20170614_164431_008.jpg","IMG_20170614_164433_045.jpg"]
These subtle differences make the difference for our For Each loop
So I now have another collection that I will perform another ForEach loop on (so I am looping through however many attachments are contained within each attachment control).
The variable that is output from the ForEach loop is the name of my attachment, with a snag, I need to perform another Regex to remove the trailing ";" on the string (if it has one) and then I'm ready to go and upload it.
Above are the screen grabs of the configuration of the "Office 365 Upload File" action.
A couple of things to explain here.
File to Upload - We're uploading content that already exists in SharePoint, but if you didn't know, attachments are stored in a hidden folder within the List that the item belongs to, so our URL here is "Lists/LISTNAME/attachments/IDOFITEM/Attachmentname.jpg".
Folder path - This is the name of the library the file will be uploaded to PLUS any folders within the library that you want the file to be placed into.
Fields - These are the pieces of metadata we will use for our new documents/files.
The final piece for our requirement is the Run If. This is to capture any instances where there is no attachment in a control. If this is the case the string that should be the filename, will simply be a i ] and our Run If makes sure the variable doesn't equal this before trying to upload, otherwise the upload fails and the workflow falls over.