Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Liferay.Upload Component Usage for Multi-file Upload

Developing a custom portlet to upload multiple files in Liferay 6.2. Found the Liferay.Upload component while going through Liferay Source Code in the Document Library Portlet at the following location:

https://github.com/liferay/liferay-portal/blob/master/portal-web/docroot/html/portlet/document_library/upload_multiple_file_entries.jsp

We want to reuse this component, but unable to find any documentation regarding the usage.

  1. How do we use the Liferay.Upload component? What do each of the inputs mean & do?
  2. Can we re-use this Liferay.Upload in our custom portlet?
  3. Any concrete documentation on the usage of Liferay.Upload?
  4. Any already implemented portlets available on the web with the Source Code available on the web?

Given below is the extract of the usage of the Liferay Upload component:

<aui:script use="liferay-upload">
    new Liferay.Upload(
        {
            boundingBox: '#<portlet:namespace />fileUpload',
            deleteFile: '<liferay-portlet:actionURL doAsUserId="<%= user.getUserId() %>"><portlet:param name="struts_action" value="/document_library/edit_file_entry" /><portlet:param name="<%= Constants.CMD %>" value="<%= Constants.DELETE_TEMP %>" /><portlet:param name="folderId" value="<%= String.valueOf(folderId) %>" /></liferay-portlet:actionURL>&ticketKey=<%= ticket.getKey() %><liferay-ui:input-permissions-params modelName="<%= DLFileEntryConstants.getClassName() %>" />',
            fileDescription: '<%= StringUtil.merge(PrefsPropsUtil.getStringArray(PropsKeys.DL_FILE_EXTENSIONS, StringPool.COMMA)) %>',
            maxFileSize: '<%= PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE) %> B',
            metadataContainer: '#<portlet:namespace />commonFileMetadataContainer',
            metadataExplanationContainer: '#<portlet:namespace />metadataExplanationContainer',
            namespace: '<portlet:namespace />',
            tempFileURL: {
                method: Liferay.Service.bind('/dlapp/get-temp-file-entry-names'),
                params: {
                    groupId: <%= scopeGroupId %>,
                    folderId: <%= folderId %>,
                    tempFolderName: 'com.liferay.portlet.documentlibrary.action.EditFileEntryAction'
                }
            },
            tempRandomSuffix: '<%= EditFileEntryAction.TEMP_RANDOM_SUFFIX %>',
            uploadFile: '<liferay-portlet:actionURL doAsUserId="<%= user.getUserId() %>"><portlet:param name="struts_action" value="/document_library/edit_file_entry" /><portlet:param name="<%= Constants.CMD %>" value="<%= Constants.ADD_TEMP %>" /><portlet:param name="folderId" value="<%= String.valueOf(folderId) %>" /></liferay-portlet:actionURL>&ticketKey=<%= ticket.getKey() %><liferay-ui:input-permissions-params modelName="<%= DLFileEntryConstants.getClassName() %>" />'
        }
    );
</aui:script>

Any pointers are highly appreciated!!

like image 979
Ashok Goli Avatar asked Mar 17 '23 06:03

Ashok Goli


2 Answers

I gave it a shot based on Pawel's links and succeeded in a sort-of POC.

view.jsp

<%@page import="com.liferay.portal.kernel.util.ParamUtil"%>
<%@page import="com.liferay.portal.kernel.portlet.LiferayWindowState"%>
<%@page import="com.liferay.portal.kernel.util.StringPool"%>
<%@page import="com.liferay.portal.kernel.util.PropsKeys"%>
<%@page import="com.liferay.portal.kernel.util.PrefsPropsUtil"%>
<%@page import="com.liferay.portal.kernel.util.StringUtil"%>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui"%>

<portlet:defineObjects />

This is the <b>Liferay File Upload</b> portlet in View mode.

<portlet:actionURL name="uploadFile" var="uploadFileURL" >
    <portlet:param name="jspPage" value="/html/singefileuploadaction/view.jsp" />
</portlet:actionURL>

<portlet:resourceURL var="importPortletURL" id="uploadSubmit">
    <portlet:param name="jspPage" value="/html/singefileuploadaction/view.jsp" />
</portlet:resourceURL>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>


<aui:form action="<%= importPortletURL %>" cssClass="lfr-export-dialog" method="post" name="fm1">

    <div class="lfr-dynamic-uploader">
        <div class="lfr-upload-container" id="<portlet:namespace />fileUpload">
            &nbsp;
        </div>
    </div>
    <div id="<portlet:namespace/>fallback"></div>

        <aui:button-row>
            <aui:button cssClass='hide' name="continueButton" type="submit" value="Continue" />
        </aui:button-row>

    <aui:script use="liferay-upload,aui-base">
        var liferayUpload = new Liferay.Upload({
            allowedFileTypes: '<%= StringUtil.merge(PrefsPropsUtil.getStringArray(PropsKeys.DL_FILE_EXTENSIONS, StringPool.COMMA)) %>',
            container: '#<portlet:namespace />fileUpload',
            maxFileSize: <%=Long.parseLong(PrefsPropsUtil.getString(PropsKeys.DL_FILE_MAX_SIZE)) %> / 1024,
            namespace:'<portlet:namespace />',
            uploadFile: '<%=uploadFileURL.toString()%>',        
            tempFileRemoved: function(){console.log('Temp File Removed');},
            'strings.dropFilesText': 'Drop Files Here to Upload.',
            'strings.dropFileText': 'Drop File Here to Upload.',
            'strings.selectFileText': 'Select File to Upload.',
            'strings.selectFilesText': 'Select Files to Upload.',
            'strings.fileCannotBeSavedText': 'File cannot be saved.',
            'strings.pendingFileText': 'This file was previously uploaded but not actually saved',
            'strings.uploadsCompleteText': 'Upload is complete. Please save.',
            multipleFiles: false

        });

        <!-- ASHOK: !IMPORTANT-DO NOT REMOVE-This code is to re-position the Upload Component HTML code which is placed on top of the page by default: Might be a BUG?? -->
        $( document ).ready(function() {
            $('.component.liferayupload').appendTo("#<portlet:namespace />fileUpload");
        });

        var continueButton = A.one('#<portlet:namespace />continueButton');

        function toggleContinueButton() {
            var uploadedFiles = liferayUpload._fileListContent.all('.upload-file.upload-complete');
            if (uploadedFiles.size() == 1) {
                console.log('One file Upload');
                console.log(uploadedFiles);
                continueButton.show();
            }
            else {
                console.log(uploadedFiles);
                continueButton.hide();
            }
        }


        <!-- Ashok: Upload Component Events BEGIN-->
        <!-- Ashok: Fired when File Upload STARTS-->
        liferayUpload._uploader.on(
                'fileuploadstart',
                function(event) {
                    console.log('File Upload Start');               
                }
            );  
        <!-- Ashok: Fired when File Upload is COMPLETE-->
        Liferay.on(
                'uploadcomplete',
                function(event) {
                    console.log('File Upload Complete');
                }
            );
        <!-- Ashok: Fired when All Uploads are COMPLETE-->
        liferayUpload._uploader.on(
                'alluploadscomplete',
                function(event) {
                    console.log('All Uploads Complete');
                    toggleContinueButton();
                }
            );      
        <!-- Ashok: Fired when Temp file is REMOVED-->
        Liferay.on(
                'tempFileRemoved',
                function(event) {
                    console.log('Temp File Removed');
                    toggleContinueButton();
                }
            );      
        <!-- Ashok: Upload Component Events END-->


        $('#<portlet:namespace />continueButton').on(
            'click',
            function(event) {
                event.preventDefault();

                $('#<portlet:namespace />fm1').ajaxSubmit(
                    {
                        success: function(responseData) {
                            <%-- $('#<portlet:namespace />exportImportOptions').html(responseData); --%>
                        }
                    }
                );
            }
        );
    </aui:script>


</aui:form>

SingeFileUploadAction.java

package com.ashok.liferay.upload;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;

import com.liferay.portal.kernel.upload.UploadPortletRequest;
import com.liferay.portal.util.PortalUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;

/**
 * Portlet implementation class SingeFileUploadAction
 */
public class SingeFileUploadAction extends MVCPortlet {
  public void uploadFile(ActionRequest actionRequest,
          ActionResponse actionResponse) throws IOException, PortletException {
      System.out.println("In SingeFileUploadAction");
      UploadPortletRequest uploadRequest=PortalUtil.getUploadPortletRequest(actionRequest);
      File file =uploadRequest.getFile("file");
      String fileName = uploadRequest.getFileName("file");
      System.out.println("FileName:"+fileName);
      //Mike Test
      Map<String, String[]> reqMap = actionRequest.getParameterMap();
      System.out.println("Printing all actionRequest Params");
      for (Map.Entry<String, String[]> entry : reqMap.entrySet())
      {
          System.out.println(entry.getKey() + "/" + Arrays.toString(entry.getValue()));
      }

      System.out.println("----------\nPrinting all uploadRequest Params");
      Map<String, String[]> upReqMap =uploadRequest.getParameterMap();
      for (Map.Entry<String, String[]> entry : upReqMap.entrySet())
      {
          System.out.println(entry.getKey() + "/" + Arrays.toString(entry.getValue()));
      }

      System.out.println(file.getName());

  }
  public void uploadSubmit(ResourceRequest resourceRequest,
      ResourceResponse resourceResponse)  {
    System.out.println("In uploadSubmit");
    UploadPortletRequest uploadRequest=PortalUtil.getUploadPortletRequest(resourceRequest);
//    File file =uploadRequest.getFile("file");
//    System.out.println(file.getName());

  }
}

Liferay File Upload

like image 200
Ashok Goli Avatar answered Apr 01 '23 17:04

Ashok Goli


After trying to customize this component for my needs, I would recommend a different way to implement file uploading in Liferay.

The lack of documentation of the Liferay.Upload Component plus the complexity of the underlaying code of the Liferay File Upload portlet makes it a difficult path to customize the file uploading implemented in Liferay.

My recommendation is the following: create a new custom portlet and use the jQuery library: jQuery File UPload plugin. Visit its website here. It is a well written library with decent documentation, you can adapt it to your needs since it covers a lot of the settings you would expect in a file uploader.

A summary of how the jsp view in your portlet would be:

<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui"%>

<portlet:defineObjects />

File Bulk Uploader

<portlet:actionURL var="uploadFileURL" name="uploadFiles"/>

<script>
  $(document).ready(function(){
    $("#multipleupload").uploadFile({
      url:"<%= uploadFileURL.toString() %>",
      multiple:true,
      dragDrop:true,
      sequential:true,
      sequentialCount:1
    });
  });
</script>

<div id="multipleupload">Upload</div>

As you can see, using this library makes a really simple implementation of the view, providing a file uploader. Implement afterwards your portlet class action like this:

public void uploadFiles(ActionRequest request, ActionResponse response) throws PortletException, IOException, SystemException, PortalException{

  UploadPortletRequest uploadRequest = PortalUtil.getUploadPortletRequest(request);
  Enumeration<?> paramEnum = uploadRequest.getParameterNames();
  File tempFile;
  Map<String, File> fileMap = new LinkedHashMap<String, File>();

  while (paramEnum.hasMoreElements()){
    String parameter = (String) paramEnum.nextElement();
    if (parameter.startsWith("file")){
      tempFile = uploadRequest.getFile(parameter);

      //******************************************
      //do what you need with the file here
      //******************************************
    }
  }
}

When debugging paramEnum, it gets a "file" parameter each time a dragged and dropped file is processed for upload. This is the sequential mechanism and so, the uploadFiles action is triggered for each file:

paramEnum debugging

like image 29
evaldeslacasa Avatar answered Apr 01 '23 18:04

evaldeslacasa