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 (singleParamb0] == 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.