How to upload Attachments via remote action (Jquery) in visualforce page

by Rijwan Mohmmed
how-to-upload-attachments-via-remote-action-jquery-in-visualforce-page

Hello folks, today we will discuss how to upload Attachments via remote action (Jquery) in Visualforce page. First of all, we need a record id to upload the attachment so we will get recordId from the apex controller and then we create a Visualforce page to upload the attachments.

Apex Class: uploadattachCtrl

In the Apex class, we create a method for retrieving attachments for querying all related attachments from related parent records Also we create a remote action method for uploading the attachments

public class uploadattachCtrl {
    public List<ContentVersion> lstContentVersionWrappers{get;set;}
    public string objAttParentId{get;set;}
    public uploadattachCtrl(){
        for(Account acc : [select id from Account LIMIT 1]){
            objAttParentId = acc.id;
        }
        this.retriveAttachments();
    }
    public void dummyrefresh(){
        this.retriveAttachments();
    }
    public void retriveAttachments(){
        try{ 
            lstContentVersionWrappers = new list<ContentVersion>();
            String strThreadId = '';
            //string objAttParentId = '';
            if(objAttParentId != null && string.isNotBlank(objAttParentId)){
                set<String> ConDocIds = new set<String>();
                for(ContentDocumentLink cdl : [select LinkedEntityId,ContentDocumentId from  ContentDocumentLink where LinkedEntityId = : objAttParentId]){
                    ConDocIds.add(cdl.ContentDocumentId) ;
                }
                for(ContentVersion CV:[select id,title,description,createdbyid,ContentSize,lastmodifieddate,contentdocumentid from contentVersion where ContentDocumentId  In :ConDocIds]){
                    lstContentVersionWrappers.add(CV);
                }
            }
        }catch(Exception ex){
            //handle catch
        }
    }
    @RemoteAction
    public static String uploadAttachments(String filename, String fileData, String record,String description) {
        if(fileData==null)
            return String.valueOf('Invalid file data.');
        String base64 = fileData.substring(fileData.indexOf(',')+1);
        Blob actualdata = EncodingUtil.base64Decode(base64);
        
        try{
            List<ContentVersion> FileListToInsert = new list<ContentVersion>();
            ContentVersion cVersion = new ContentVersion();
            cVersion.PathOnClient = filename;//File name with extention
            cVersion.Title = filename;//Name of the file
            cVersion.VersionData = actualdata;//File content
            cVersion.Description = Description;
            FileListToInsert.add(cVersion);
            if(FileListToInsert.size()>0){
                insert FileListToInsert;
                Set<String> Condoc = new Set<String>();
                set<id> ContentVersionID = new set<id>();
                for(ContentVersion CV: FileListToInsert){
                    ContentVersionID.add(CV.Id);
                }
                for(ContentVersion cv: [select contentDocumentid from ContentVersion where id in : ContentVersionID]){
                    Condoc.add(cv.ContentDocumentId);
                }
                list<ContentDocumentLink> cldlist = new list<ContentDocumentLink>();
                for(String s : Condoc){
                    ContentDocumentLink cdl = new ContentDocumentLink();
                    cdl.ContentDocumentId =s;
                    cdl.LinkedEntityId = record;
                    cdl.sharetype = 'I';
                    cldlist.add(cdl);
                }
                if(cldlist.size()>0)
                    insert cldlist;
                return String.valueOf('Upload Successful!');
            }
            
            /******* Insert Attachments ******/
            Attachment attch = new Attachment();
            attch.name = filename;
            attch.parentId  = record;
            attch.body = actualdata;
            insert attch;
            /**********************************/
            
        }catch(Exception ex){
            System.debug(ex);
            return String.valueOf('Error');
        }
        return String.valueOf('');
    }

}

Visualforce Page: uploadattach

In the Visualforce page, we will set recordId variable in input hidden. Create a table to show the attachments list. For uploading the attachments we create a Modal Popup and create two fields. We will upload the attachment via the Jquery method without reloading the Page.

<apex:page controller="uploadattachCtrl">
   <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
   <apex:slds />
   <apex:form >
      <apex:actionStatus id="mystatus" >
         <apex:facet name="start">
            <div style="position: fixed; left: 0; top: 0; bottom: 0; right: 0; z-index: 9999; margin: 30% 50%">
               <!-- SPINNER -->
               <div style=" position:fixed;left: 50%; top:  50%;height:32px; width:32px; margin-left: -32px; margin-top:-32px;z-index: 9999;" id="spinner" class="slds-spinner_container slds-is-relative" >
                  <div role="status" class="slds-spinner slds-spinner--large slds-spinner--brand">
                     <div class="slds-spinner__dot-a"></div>
                     <div class="slds-spinner__dot-b"></div>
                  </div>
               </div>
               <!-- / SPINNER -->
            </div>
            <div class="slds-backdrop slds-backdrop_open" style="opacity: 0;"></div>
         </apex:facet>
      </apex:actionStatus>
      <!-- SPINNER -->
      <div id="spinnerRemote" class="slds-hide" style="z-index:2000000">
         <div class="demo-only">
            <div class="slds-spinner_container">
               <div role="status" class="slds-spinner slds-spinner_medium slds-spinner_brand" style="z-index: 2000000;position: fixed;">
                  <div class="slds-spinner__dot-a"></div>
                  <div class="slds-spinner__dot-b"></div>
               </div>
            </div>
            <div class="slds-backdrop slds-backdrop_open" style="opacity: 0;"></div>
         </div>
      </div>
      <!-- / SPINNER -->
      <!-- Page Header Start -->
      <div class="slds-tabs_card">
         <div class="slds-page-header">
            <div class="slds-page-header__row">
               <div class="slds-page-header__col-title">
                  <div class="slds-media">
                     <div class="slds-media__figure">
                        <span class="slds-icon_container slds-icon-doctype-xml" title="Description of icon when needed">
                           <svg class="slds-icon slds-page-header__icon" aria-hidden="true">
                              <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="{!URLFOR($Asset.SLDS, 'assets/icons/doctype-sprite/svg/symbols.svg#attachment')}" />
                           </svg>
                           <span class="slds-assistive-text">Description of icon when needed</span>
                        </span>
                     </div>
                     <div class="slds-media__body">
                        <div class="slds-page-header__name">
                           <div class="slds-page-header__name-title">
                              <h1>
                                 <span class="slds-page-header__title slds-truncate" title="Rohde Corp - 80,000 Widgets">Attachments</span>
                              </h1>
                           </div>
                        </div>
                        <p class="slds-page-header__name-meta"></p>
                     </div>
                  </div>
               </div>
               <div class="slds-page-header__col-actions">
                  <div class="slds-page-header__controls">
                     <div class="slds-page-header__control">
                        <ul class="slds-button-group-list">
                           <li>
                              <button class="slds-button slds-button_neutral" onclick="ShowHideAtachmentPopup();return false">Add Attachment </button>
                           </li>
                        </ul>
                     </div>
                  </div>
               </div>
            </div>
         </div>
         <!-- Page Header End -->
         <!-- start attachment table -->
         <apex:actionRegion >
            <apex:actionFunction name="dummyrefresh" action="{!dummyrefresh}" reRender="AttachmentTablePanel,HandleAttachmentsPopUp,attachment_Popup_Content,AttachmentPopupFooter" status="mystatus"/>
         </apex:actionRegion>
         <apex:outputPanel id="AttachmentTablePanel">
            <apex:outputPanel layout="block" id="WitnessTableId" styleClass="slds-m-top_small" >
               <div style="min-width:10rem" class="slds-scrollable_x" >
                  <table id="WitnessTable" class="slds-table slds-table_bordered slds-table_fixed-layout slds-max-medium-table_stacked-horizontal">
                     <thead>
                        <tr class="slds-line-height_reset">
                           <th class="slds-text-title_caps">
                              <div class="slds-truncate"> Title </div>
                           </th>
                           <th class="slds-text-title_caps">
                              <div class="slds-truncate"> File Size </div>
                           </th>
                           <th class="slds-text-title_caps">
                              <div class="slds-truncate">  Description </div>
                           </th>
                           <th class="slds-text-title_caps">
                              <div class="slds-truncate"> Last Modified Date </div>
                           </th>
                        </tr>
                     </thead>
                     <tbody>
                        <apex:repeat value="{!lstContentVersionWrappers}" var="attachment">
                           <tr aria-selected="false" class="slds-hint-parent">
                              <td data-label="title" role="gridcell">
                                 <apex:outputPanel >
                                    {!attachment.Title}
                                 </apex:outputPanel>
                              </td>
                              <td data-label="Size" role="gridcell">
                                 <apex:outputText value="{!ROUND(attachment.ContentSize / 1000, 0)} KB" />
                              </td>
                              <td data-label="Description" role="gridcell">
                                 <apex:outputText value="{!attachment.Description}" />
                              </td>
                              <td data-label="Date" role="gridcell">
                                 <apex:outputText value="{0, date, MMMM d','  yyyy}">
                                    <apex:param value="{!attachment.LastModifiedDate}" />
                                 </apex:outputText>
                              </td>
                           </tr>
                        </apex:repeat>
                     </tbody>
                  </table>
               </div>
            </apex:outputPanel>
         </apex:outputPanel>
      </div>
      <!-- ---->
      <!---------------------------------------------------- Attachment Popup Starts ------------------------------------------------->
      <div id="HandleAttachmentsPopUp" style="height: 640px;position: absolute;" class="slds-hide">
         <section role="dialog" tabindex="-1" aria-labelledby="modal-heading-01" aria-modal="true" aria-describedby="modal-content-id-1" class="slds-modal slds-fade-in-open">
            <div class="slds-modal__container">
               <header class="slds-modal__header">
                  <button class="slds-button slds-button_icon slds-modal__close slds-button_icon-inverse" onclick="af_ResetAtt();return false;" title="Close">
                     <svg class="slds-button__icon slds-button__icon_large" aria-hidden="true">
                        <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="{!URLFOR($Asset.SLDS, 'assets/icons/utility-sprite/svg/symbols.svg#close')}" />
                     </svg>
                     <span class="slds-assistive-text">Close</span>
                  </button>
                  <h2 id="modal-heading-01" class="slds-text-heading_medium slds-hyphenate">Add Attachment</h2>
               </header>
               <div class="slds-modal__content slds-p-around_medium" id="modal-content-id-1">
                  <apex:outputPanel id="attachment_Popup_Content">
                     <input type="hidden" value="{!objAttParentId}" id="WitnessIDRemotee"/>
                     <apex:actionRegion >
                        <!---------------------- Attachment related action Functions -------------------------------------------->
                        <apex:actionFunction name="af_ResetAtt" rerender="HandleAttachmentsPopUp,attachment_Popup_Content,AttachmentPopupFooter" oncomplete="ShowHideAtachmentPopup();" status="mystatus"/>
                        <!------------------------------------------------------------------------------------------------------->
                     </apex:actionRegion>
                     <apex:outputPanel >
                        <div class="slds-text-body_regular"></div>
                        <div class="slds-text-body_regular slds-m-top_medium" style="font-style:italic;margin-left:10px;margin-bottom:15px;color:#d21e00;"></div>
                        <apex:actionRegion >
                           <div class="slds-form-element">
                              <label class="slds-form-element__label" for="form-element-01">File</label>
                              <div class="slds-form-element__control ">
                                 <input type="file" id="fileInput" value="" fileName=""/>
                              </div>
                              <div style="height:0.7rem;"></div>
                              <label class="slds-form-element__label" for="form-element-01">Description</label>
                              <div class="slds-form-element__control ">
                                 <textarea id="description_input" placeholder="" class="slds-textarea" autocomplete="none"></textarea>
                              </div>
                           </div>
                        </apex:actionRegion>
                     </apex:outputPanel>
                  </apex:outputPanel>
               </div>
               <apex:outputPanel id="AttachmentPopupFooter" layout="block" styleclass="slds-modal__footer">
                  <apex:outputPanel >
                     <button class="slds-button slds-button_neutral" onclick="af_ResetAtt();return false;">Cancel</button>
                     <button class="slds-button slds-button_brand" onclick="af_AttachmentSaveJquery();return false;" >Save</button> 
                  </apex:outputPanel>
               </apex:outputPanel>
            </div>
         </section>
         <div class="slds-backdrop slds-backdrop_open"></div>
      </div>
      <script>
         function ShowHideAtachmentPopup(){
             var popUp=$('div[id$=HandleAttachmentsPopUp]');
             if($(popUp).hasClass('slds-hide')){
                 $(popUp).removeClass('slds-hide').addClass('slds-show');
             }else if($(popUp).hasClass('slds-show')){
                 $(popUp).removeClass('slds-show').addClass('slds-hide');
             }
         }
         /*************************** Upload files via jquery **************************************************/
         function af_AttachmentSaveJquery() {
         var popUp=$('div[id$=HandleAttachmentsPopUp]');
          $('#spinnerRemote').addClass('slds-show').removeClass('slds-hide');
          var recordId =  $('#WitnessIDRemotee').val(); 
          var  jsonObj = [];
          let spinneroff = true;
          for(var i=1;i<=1;i++){
              let fileInput = $('#fileInput');
              let fileDescription = $('#description_input').val();
              if (!$.trim( fileInput.val() ).length == 0) {
                  spinneroff = false;
                  let file = fileInput[0].files[0];
                  let fileName = getFileNameWithExtension(file);
                  let reader = new FileReader();
                  let item = {}
                  item["filename"] = fileName;
                  item["description"] = fileDescription;
                  reader.onloadend = function(){
                      item["filedata"] = reader.result;
                      uploadToSalesforce(fileName,reader.result,recordId,fileDescription); 
                  }
                  reader.readAsDataURL(file);
              }
          }
          console.log(spinneroff);
          if(spinneroff){
              $('#spinnerRemote').addClass('slds-hide').removeClass('slds-show');
              $(popUp).removeClass('slds-show').addClass('slds-hide');
           }
         }
         function uploadToSalesforce(fileName,contentOfFile,recordForWhichUploading,description) {
         var popUp=$('div[id$=HandleAttachmentsPopUp]');
         $('#spinnerRemote').addClass('slds-show').removeClass('slds-hide');
         Visualforce.remoting.Manager.invokeAction(
             '{!$RemoteAction.uploadattachCtrl.uploadAttachments}', 
             fileName, contentOfFile, recordForWhichUploading,description,
             function(result, event){
                 console.log(result);
                 $('#spinnerRemote').addClass('slds-hide').removeClass('slds-show');
                 $(popUp).removeClass('slds-show').addClass('slds-hide');
                 dummyrefresh();
                 if (event.status) {
                     status = 'Upload Successful' + result;
                 } else if (event.type === 'exception') {
                     status = 'Upload Error';
                 } else {
                     status = 'Upload Error';
                 }
                 
             }, 
             {escape: true}
         );
         }
         function getFileNameWithExtension(file) {
         var extIndex = file.name.lastIndexOf('.');
         var extension = file.name.substring(extIndex);
         var fileName = file.name.substring( 0, extIndex );
         fileName = fileName.replace(/\./g, '_');
         fileName += extension;
         return fileName;
         }
         
         /*******************************************************************************************************/
      </script>
   </apex:form>
</apex:page>
What’s your Reaction?
+1
1
+1
0
+1
0
+1
0
+1
0
+1
0

You may also like

2 comments

lakhan August 1, 2022 - 7:14 am

No remote action found error

Reply
Rijwan Mohmmed August 1, 2022 - 6:07 pm

Check apex class and method annotation should be @remoteAction

Reply

Leave a Comment