In this example we will create a simple Webdynpro ABAP component called ZWDA_UI5_FILEUPLOADER to show how to use SAP UI5 component sap.m.UploadCollection to upload multiple files in your webdynpro application.
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 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
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.
Right click on the HtmlIsland and choose Script Insert
5 – SAP GUI screenshot Webdynpro Script Insert Menu
Rename it to UI5_CORE_SCRIPT
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
ID ID_CSA
name id
value sap-ui-bootstrap
7 – SAP GUI screenshot Webdynpro Custom Attribute Properties
ID LIB_CSA
name data-sap-ui-libs
value sap.m
8 – SAP GUI screenshot Webdynpro Custom Attribute Properties
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
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 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
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.
Now we need to create 4 actions for our view
16 – SAP GUI screenshot Webdynpro View action creation
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.
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.
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.
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.
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 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 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.
21 – SAP GUI screenshot Webdynpro Application Drop Files
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
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/