Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
Wandersonwos
Participant

In the SAP Note 3280607 - WDA: Multiple File Upload, the SAP suggests using an SAP UI5 component to upload multiple files in the Webdynpro application:



The WebDynpro FileUpload control does not support multiple file upload, but only one file at a time.

In higher SAP_UI releases (SAP_UI 7.54 onwards) the solution suggestion would be to embed the SAP UI5 control UploadSet into a WebDynpro HTML Island or alternatively into a WebDynpro iFrame control.


In this example, we will create a simple WebDynpro ABAP component called ZWDA_UI5_FILEUPLOADER to show how to embed the SAP UI5 control into a WebDynpro HTML Island.



Create the Webdynpro ABAP component ZWDA_UI5_FILEUPLOADER



1 - Eclipse screenshot Webdynpro Component Creation


 

Create a node called FILES_UPLOADED with cardinality/selection 0…N and the following attributes:

































name data element category length
FILENAME_WITH_FILETYPE STRING
MIMETYPE W3CONTTYPE char 128
SIZE STRING
CONTENT XSTRING


2 - SAP GUI screenshot Webdynpro Context Node Creation


Context Mapping of the node FILES_UPLOADED 


3 - SAP GUI screenshot Webdynpro Context Mapping.png



Create a CTable to show and test the files that was uploaded


Create a CTable to show all the files that will be uploaded ( context node FILES_UPLOADED) with the following columns:























Column Cell Editor property bind
COL_FILEDOWNLOAD FileDownload (See the next picture)
COL_MIMETYPE TextView MAIN.FILES_UPLOADED.MIMETYPE
COL_SIZE TextView MAIN.FILES_UPLOADED.SIZE

 

Filedownload column bind properties:


4 - SAP GUI screenshot Webdynpro File Download column properties



Html Island


Create an HtmlIsland with the name HTML_ISLAND_FILE_UPLOADER_UI5

Now we will add two scripts on the HtmlIsland, the first one is to call the SAP UI5 library, and the other is to call our custom javascript code. 

Script to call the SAP UI5 library


Right click on the HtmlIsland and choose Script Insert


5 - SAP GUI screenshot Webdynpro Script Insert Menu


 

Rename it to UI5_CORE_SCRIPT

 

Adding Custom Scripts Attributes


Now we need to add 2 Custom Script Attributes, to do that perform the following action 2 times:

Right click on the HtmlScript UI5_CORE_SCRIPT and choose Custom Attribute Insert


6 - SAP GUI screenshot Webdynpro Custom Attribute Insert Menu


After change the properties of theses Script Attributes

  • The first one is to perform the UI5 Bootstrap


ID ID_CSA

name id

value sap-ui-bootstrap


7 - SAP GUI screenshot Webdynpro Custom Attribute Properties




  • The second one is used to load all the UI5 libraries that we need (use comma to separate the names of the UI5 libraries if you need more than one, example “sap.ui.commons,sap.m”). In our example, we only need the UI5 library sap.m:


ID LIB_CSA

name data-sap-ui-libs

value sap.m


8 - SAP GUI screenshot Webdynpro Custom Attribute Properties



Script to call our custom javascript code


Right click on the HtmlIsland and choose Script Insert


9 - SAP GUI screenshot Webdynpro Script Insert Menu


Rename the ID property to CUSTOM_JS

Fill the source property with the name FileUploaderUI5.js (it is the name of the MIME object that we will import in the next step).


10 - SAP GUI screenshot Webdynpro Html Script Properties



Import your Javascript code as a MIME Object


Create a Javascript file in your preferred IDE.

Paste the following code in the Javascript File:
var MyFileUploader = MyFileUploader || {
init: function (oCallbackApi, maxFilenameLength, maxFileSize, fileType) {
if (fileType !== null) {
var filetypeArray = fileType.split(",");
} else {
filetypeArray = null
}
this.oCallbackApi = oCallbackApi;
this.oFileUploader = new sap.m.UploadCollection({
maximumFilenameLength: parseInt(maxFilenameLength),
maximumFileSize: parseInt(maxFileSize), // Specifies a file size limit in megabytes
multiple: true,
sameFilenameAllowed: false,
instantUpload: false,
fileType: filetypeArray,
change: this.onChange,
typeMissmatch: this.ontypeMissmatch,
fileSizeExceed: this.onfileSizeExceed,
filenameLengthExceed: this.onfilenameLengthExceed,
});

this.oFileUploader.placeAt("FileUploadUI5");
},
onChange: function (oControlEvent) {
for (let index = 0; index < oControlEvent.mParameters["files"].length; index++) {
const file = oControlEvent.mParameters["files"][index];
MyFileUploader.uploadToCallbackAPI(file);
}
},
ontypeMissmatch: function (oControlEvent) {
let file = oControlEvent.mParameters["files"][0];
MyFileUploader.oCallbackApi.fireEvent('UI5TypeMismatch', '{"filename":"' + file.name + '",' + '"filetype":"' + file.fileType + '"}');
},
onfilenameLengthExceed: function (oControlEvent) {
let file = oControlEvent.mParameters["files"][0];
MyFileUploader.oCallbackApi.fireEvent('UI5NameLenghtExceed', file.name );
},
onfileSizeExceed: function (oControlEvent) {
let file = oControlEvent.mParameters["files"][0];
MyFileUploader.oCallbackApi.fireEvent('UI5SizeExceed', file.name );
},
uploadToCallbackAPI(file) {

if (file == null) {
return;
}
var oFileReader = new FileReader();
var fileName = file.name.split(".")[0];
var fileType = file.name.split(".")[1];
var mimetype = file.type;
var size = file.size;

oFileReader.onload = function (evt) {
var raw = evt.target.result;
var hexString = MyFileUploader.convertBinaryToHex(raw).toUpperCase();
var fileAsJsonString = MyFileUploader.createJsonObjectForFileInfo(fileName, fileType, mimetype, size, hexString);

MyFileUploader.oCallbackApi.fireEvent('UI5Upload', fileAsJsonString);

};

oFileReader.onerror = function (evt) {
sap.m.MessageToast.show("error");
};
oFileReader.readAsArrayBuffer(file);


},
createJsonObjectForFileInfo: function (fileName, fileType, mimetype, size, hexString) {
return '{"filename":"' + fileName + '",' +
'"filetype":"' + fileType + '",' +
'"mimetype":"' + mimetype + '",' +
'"size":"' + size + '",' +
'"hexcont":"' + hexString + '"}';
},

convertBinaryToHex: function (buffer) {
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
},
removeFirstFile: function (evt) {
var oFirstFileItem = MyFileUploader.oFileUploader.getItems()[0];
MyFileUploader.oFileUploader.removeItem(oFirstFileItem);
}
}

Right click on the Webdynpro component and chose: Create > MIME Object > Import


11 - SAP GUI screenshot Webdynpro MIME Object Import


In the following popup, just click in the Save button


12 - SAP GUI screenshot Webdynpro MIME Object Import confirm


Now your Javascript code is part of your Webdynpro component as a MIME Object.


13 - SAP GUI screenshot Webdynpro MIME Object Importation result


Everytime that you need to update it, just change your Javascript file in your preferred IDE and upload it again.

To do that, perform an right click on the MIME Object and choose: Upload/Download > Upload and Replace


14 - SAP GUI screenshot Webdynpro MIME Object Replace



Create an view attributes


Create a view attribute called MO_HTML_ISLAND type ref to CL_WD_HTML_ISLAND (it will be filled in the method WDDOMODIFYVIEW).


15 - SAP GUI screenshot Webdynpro View attribute creation


Create a view attribute called MV_REMOVE_FILE type WDY_BOOLEAN (it will be filled in the method ONACTIONUI5_UPLOAD anc checked in the method WDDOMODIFYVIEW ).


15b - SAP GUI screenshot Webdynpro View attribute creation



Modify view


In the WDDOMODIFYVIEW method, put the following code:

 
METHOD wddomodifyview .

CONSTANTS:
c_file_upload_html_id TYPE string VALUE 'FileUploadUI5',
c_html_insland_id TYPE string VALUE 'HTML_ISLAND_FILE_UPLOADER_UI5',
c_ui5_core_script_id TYPE string VALUE 'UI5_CORE_SCRIPT'.

IF first_time = abap_true.

" use central UI5-version provided by WDA
DATA(lv_script_string) = cl_wd_utilities=>get_ui5_root_path( ).
IF lv_script_string IS NOT INITIAL.
CONCATENATE lv_script_string 'sap-ui-core.js' INTO lv_script_string.
CONDENSE lv_script_string NO-GAPS.
CAST cl_wd_html_script( view->get_element( id = c_ui5_core_script_id ) )->set_source( value = lv_script_string ).
ENDIF.

" set static html
DATA(lv_static_html) = |<div id="{ c_file_upload_html_id }" style="height:100%"></div>|.

wd_this->mo_html_island = CAST cl_wd_html_island( view->get_element( c_html_insland_id ) ).
wd_this->mo_html_island->set_static_html( lv_static_html ).

" Call the Init Javascript function and pass the Webdynpro callback API to allow the JavaScript code call Webdynpro Actions
wd_this->mo_html_island->add_script_call( cl_wd_html_script_call=>new_call(
)->variable( `MyFileUploader`
)->function( `init`
)->add_callback_api(
)->add_string( '100' " Maximum Filename Length
)->add_string( '1' " Maximum FileSize (Specifies a file size limit in megabytes)
)->add_string( 'jpg,pdf,txt,xls,xlsx,png' " FileTypes (use comma as separator)
* )->add_null( " Use add_null if all the file types should be allowed
) ).

ELSEIF wd_this->mv_remove_file = abap_on.

wd_this->mo_html_island->add_script_call( cl_wd_html_script_call=>new_call(
)->variable( `MyFileUploader`
)->function( `removeFirstFile` ) ).

wd_this->mv_remove_file = abap_off.

ENDIF.

ENDMETHOD.

 

Create 4 View Actions


Now we need to create 4 actions for our view


16 - SAP GUI screenshot Webdynpro View action creation



Create an View Action to be called by the Javascript code


In your view, create a new action called: UI5_UPLOAD 

In that action put the following code:
METHOD onactionui5_upload .

TYPES:
BEGIN OF ty_file_uploaded,
filename TYPE string,
filetype TYPE string,
mimetype TYPE string,
size TYPE string,
hexcont TYPE string,
END OF ty_file_uploaded.

DATA ls_file_uploaded_js TYPE ty_file_uploaded.

DATA ls_files_uploaded_wd TYPE wd_this->element_files_uploaded.
DATA:
BEGIN OF ls_file_size,
value TYPE k_bytes,
unit TYPE cacs_byte_unit,
END OF ls_file_size.

IF wdevent IS NOT BOUND.
RETURN.
ENDIF.

DATA(lv_file_upload_json) = wdevent->get_string( `DATA` ).

/ui2/cl_json=>deserialize( EXPORTING json = lv_file_upload_json
CHANGING data = ls_file_uploaded_js ).

ls_files_uploaded_wd-mimetype = ls_file_uploaded_js-mimetype.
ls_files_uploaded_wd-content = ls_file_uploaded_js-hexcont.
ls_files_uploaded_wd-filename_with_filetype = |{ ls_file_uploaded_js-filename }.{ ls_file_uploaded_js-filetype }|.

CALL FUNCTION 'CACS_CONVERT_BYTE'
EXPORTING
i_byte = CONV k_bytes( ls_file_uploaded_js-size )
IMPORTING
e_value = ls_file_size-value
e_unit = ls_file_size-unit.

ls_files_uploaded_wd-size = |{ ls_file_size-value } { ls_file_size-unit }|.

DATA(lo_nd_files_uploaded) = wd_context->get_child_node( wd_this->wdctx_files_uploaded ).

lo_nd_files_uploaded->bind_structure( new_item = ls_files_uploaded_wd
set_initial_elements = abap_false ).

wd_this->mv_remove_file = abap_on.

ENDMETHOD.

 

Create an View Action to the File Size Exceeded error


In your view, create a new action UI5_FILE_SIZE_EXCEED

In that action put the following code:
METHOD onactionui5_file_size_exceed .

DATA(lv_filename) = wdevent->get_string( `DATA` ).

wd_this->wd_get_api( )->get_message_manager( )->report_error_message(
EXPORTING
message_text = |The File "{ lv_filename }" exceeded the size limit| ).

ENDMETHOD.

 

Create an View Action to the Name Length Exceeded error


In your view, create a new action UI5_NAME_LENG_EXCEED

In that action put the following code:
METHOD onactionui5_name_leng_exceed .

DATA(lv_filename) = wdevent->get_string( `DATA` ).

wd_this->wd_get_api( )->get_message_manager( )->report_error_message(
EXPORTING
message_text = |"{ lv_filename }" file name is longer than allowed| ).

ENDMETHOD.

Create an View Action to the Name Length Exceeded error


In your view, create a new action UI5_TYPE_MISSMATCH

In that action put the following code:
method ONACTIONUI5_TYPE_MISSMATCH .

TYPES:
BEGIN OF ty_file_uploaded,
filename TYPE string,
filetype TYPE string,
END OF ty_file_uploaded.

DATA ls_file_uploaded_js TYPE ty_file_uploaded.

IF wdevent IS NOT BOUND.
RETURN.
ENDIF.

DATA(lv_file_upload_json) = wdevent->get_string( `DATA` ).

/ui2/cl_json=>deserialize( EXPORTING json = lv_file_upload_json
CHANGING data = ls_file_uploaded_js ).

wd_this->wd_get_api( )->get_message_manager( )->report_error_message(
EXPORTING
message_text = |The File type { ls_file_uploaded_js-filetype } from the file { ls_file_uploaded_js-filename } is not allowed| ).

endmethod.

 

Create 4 Html Events in the HtmlIsland


 

Insert Event (4 times)



17 - SAP GUI screenshot Webdynpro Insert Html Event


Change its properties to:
ID HTML_EVT_UI5_UPLOAD

name UI5Upload

Events / onAction UI5_UPLOAD

 
ID HTML_EVT_UI5_SIZE_EXCEED

name UI5SizeExceed

Events / onAction UI5_FILE_SIZE_EXCEED

 
ID HTML_EVT_UI5_NAME_LENG_EXCEED

name UI5NameLenghtExceed

Events / onAction UI5_NAME_LENG_EXCEED

 
ID HTML_EVT_UI5_TYPE_MISMATCH

name UI5TypeMismatch

Events / onAction UI5_TYPE_MISSMATCH


18 - SAP GUI screenshot Webdynpro Html Events results



Create groups 


Create a group with the caption “Webdynpro ABAP” and put the CTable on it

Create a group with the caption “SAP UI5 (class sap.m.UploadCollection)” and put the Html Island on it

 

Create Webdynpro Application


Create a new Webdynpro application called ZWDA_UI5_FILEUPLOADER and test it


19 - SAP GUI screenshot Webdynpro Application Creation


The application should be appear like this:


20 - SAP GUI screenshot Webdynpro Application Initial screen


When you add multiple files to the first area using drag and drop or the “+” button, the application will perform the upload of the files to the Webdynpro component. 

Before



21 - SAP GUI screenshot Webdynpro Application Drop Files



After



22 - SAP GUI screenshot Webdynpro Application upload result


You can click on the first column to perform a download of the file.

 

The SAP UI5 component sap.m.UploadCollection can optionally validate the file types, the filesize and the filename length according to the parameters that we assign to the initialization routine present in WDDOMODIFYVIEW.
    " Call the Init Javascript function and pass the Webdynpro callback API to allow the JavaScript code call Webdynpro Actions
wd_this->mo_html_island->add_script_call( cl_wd_html_script_call=>new_call(
)->variable( `MyFileUploader`
)->function( `init`
)->add_callback_api(
)->add_string( '100' " Maximum Filename Length
)->add_string( '1' " Maximum FileSize (Specifies a file size limit in megabytes)
)->add_string( 'jpg,pdf,txt,xls,xlsx,png' " FileTypes (use comma as separator)
* )->add_null( " Use add_null if all the file types should be allowed
) ).

 

The webdynpro will receive the name of the file when an error occurs. So we can emit a error message in the webdynpro application.

 

In the following example, I tried to realize a upload of the file “A pdf file with more than 1 megabytes.pdf” that has more than 1 megabytes.


23 - SAP GUI screenshot Webdynpro Application example error


 

References


The following articles was used as reference:

https://blogs.sap.com/2015/06/30/team-fpm-creating-a-ui5-based-uibb/

https://answers.sap.com/questions/12970830/issue-in-adding-uploadcollection-ui-element-in-web.html

https://blogs.sap.com/2018/07/06/creating-a-gos-attachment-with-sapui5/
Labels in this area