There are many requirements where Approvers need to upload attachments on task form, which need to be uploaded on main item instead of task form.
I have achieved it using REST and JS.
Major Steps :
1. Create RichText Control on Text Form to show attachment and add attachment button.
2. Add JS which use REST API to add attachments
Requirement Result Screen :
On click of Show Attachment button, it loads attachments of Related item with add attachment link as shown below
on Add attachment it opens below screen and we can upload attachment by selecting file.
Solution
1. Drag a Task on workflow. Click on Edit Task form.
2. Add a Rich Text Control on form as shown in below screen
3. Edit Properties of Rich Text add below HTML in Rich text as shown below
<input id="btnAttach" ="return checkSPLoad('');" style="width:180px;" type="button" value="Show Attachments" />
<div id="divAttachs"></div>
<div id="addAttachmentDiv" style="display:none;">Select a file<br />
<strong>Name </strong>
<input class="attachmentButton" id="attachmentButton" multiple="multiple" name="attachmentButton" ="attachFile(this);" type="file" />
</div>
<div class="nf-attachmentsLink" id="idAttachmentsLink" ="showAttch();" style="height:17px;display:none;">
<img />
<a class="ms-addnew" href="#">Add Attachment</a>
</div>
4. Click On Save.
5. Select Form Setting in ribbon and add javascript.
6. Paste below script in custom javascript section.
var pollSP; var hostweburl='';
var appweburl='';
var listname='ListName';//Include list name
var itemid=ID; //Include reference of ID of item.
var file;
var contents;
var itmUrl='';
function checkSPLoad(callType){
NWF$('#btnAttach').hide();
if (clientContext){
window.clearInterval(pollSP);
hostweburl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
appweburl = decodeURIComponent(getQueryStringParameter("SPAppWebUrl"));
var layoutsPath = "/_layouts/15/";
var scriptbase = appweburl + layoutsPath;
itmUrl=hostweburl+"/Lists/"+listname+"/Attachments/"+itemid;
if(callType=='Post')
{
NWF$.getScript(scriptbase + "SP.js", function () {
NWF$.getScript(scriptbase+ "SP.RequestExecutor.js", execCrossDomainRequest);
});
}
else
{
NWF$.getScript(scriptbase + "SP.js", function () {
NWF$.getScript(scriptbase+ "SP.RequestExecutor.js", execCrossDomainGetRequest);
});
}
}
function execCrossDomainRequest() {
var contents2 = _arrayBufferToBase64(contents);
var executor = new SP.RequestExecutor(appweburl);
var digest = NWF$("#__REQUESTDIGEST").val();
executor.executeAsync(
{
url:appweburl +
"/_api/SP.AppContextSite(@target)/web/lists/getbytitle('"+listname+"')/items("+itemid+")/AttachmentFiles/add(FileName='"+file.name +"')? @target='" + hostweburl + "'",
method: "POST",
body: contents2 ,
binaryStringRequestBody: true,
contentType: "application/json;odata=verbose",
headers: { "X-RequestDigest": digest, "Accept": "application/json; odata=verbose"},
success: function (data) {
NWF$('#addAttachmentDiv').hide();
NWF$('#attachmentButton').val('');
execCrossDomainGetRequest(); NWF$('#idAttachmentsLink').show();
},
error: function (err) {
var data=JSON.parse(err.body);
;
NWF$('#idAttachmentsLink').show();
NWF$('#addAttachmentDiv').hide();
NWF$('#attachmentButton').val('');
}
});
}
function execCrossDomainGetRequest() {
var executor = new SP.RequestExecutor(appweburl);
NWF$('#divAttachs').html("Loading...");
executor.executeAsync(
{
url: appweburl + "/_api/SP.AppContextSite(@target)/web/lists/getbytitle('"+listname+"')/items("+itemid+")/AttachmentFiles?@target='" +
hostweburl + "'",
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
parseAttachment(data);
NWF$('#idAttachmentsLink').show();
},
error: function (err) {
var data=JSON.parse(err.body);
; NWF$('#btnAttach').show();
}
});
}
}
function getQueryStringParameter(paramToRetrieve) {
var params =
document.URL.split("?")[1].split("&");
for (var i = 0; i < params.length; i = i + 1) {
var singleParam = params.split("=");
if (singleParam[0] == paramToRetrieve)
return singleParam[1];
}
}
function showAttch()
{
NWF$('#addAttachmentDiv').show();
NWF$('#idAttachmentsLink').hide();
}
function parseAttachment(vdata)
{
var html='';
var data=JSON.parse(vdata.body);
var items=data.d.results;
for(i=0;i<items.length;i++)
{
html+='<a href="'+itmUrl+'//'+items.FileName+'" target="_blank">'+items.FileName+'</a><br>';
}
NWF$('#divAttachs').html(html);
}
function f"font-size: 12px;"> contents = event.target.result;
checkSPLoad('Post');;
}
function attachFile(event) {
var i = 0,
files = event.files,
len = files.length;
if (files.length > 0) {
file = files[0];
fileName = file.name;
var reader = new window.FileReader();
reader. f"font-size: 12px;"> reader. = function(event) {
console.error("File reading error " + event.target.error.code);
};
reader.readAsArrayBuffer(file);
}
return false;
}
function _arrayBufferToBase64(buffer) {
var binary = '';
var bytes = new window.Uint8Array(buffer);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes);
}
return binary;
}
Note : Update list name and id(Add reference from Item section) in top of script.
7. Save and close form.
Publish workflow and test.
Happy Nintexing.