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: 
abhimanyu_lagishetti7
Active Contributor
10,459

Introduction


This blog helps UI5/Fiori developers understand sap.m.uploader.UploadSet UI Element in detail.

Problem


The SAP UI5 Demo site explains the UploadSet sample application. However, the  site can not explain how it works with a back-end system.

Solution


Below is the step by step working example of the UploadSet UI element that I have implement. Hope this helps clarify many questions related to UploadSet.

Back-end Gateway Service Implementation


Build a Gateway Project, create an entity for attachment attributes shown below.


Gateway Project


Mark the entity as Media


Re-define Define method of the MPC Extension class to mark the Mimetype  field as content type.
  method DEFINE.
super->define( ).

data: lo_entity TYPE REF TO /iwbep/if_mgw_odata_entity_typ,

lo_property TYPE REF TO /iwbep/if_mgw_odata_property.
lo_entity = model->get_entity_type( iv_entity_name = 'Attachment' ).
IF lo_entity IS BOUND.
lo_property = lo_entity->get_property( iv_property_name = 'Mimetype').
lo_property->set_as_content_type( ).

lo_property = lo_entity->get_property( iv_property_name = 'Erdat' ).
lo_property->/iwbep/if_mgw_odata_annotatabl~create_annotation( 'sap' )->add(
iv_key = 'display-format' iv_value = 'Date' ).
ENDIF.

endmethod.

Its time to implement the Data Provider class. Starting with re-defining method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_STREAM.

this method is called when an file is being attached. The most important information we need here is the content of the file, MIME type, filename, Key ( against which we are going to save this attachment ). We are making use of importing parameter iv_slug to get some of the information. We will know how to pass this information from UI when we code for UI5.
  method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_STREAM.
DATA ls_attach TYPE ZUI_ATTACHMENTS_S.
DATA lv_xstring TYPE xstring.
DATA lr_attachments TYPE REF TO zcl_ut_ui5_attachments.
* READ TABLE it_key_tab ASSIGNING FIELD-SYMBOL(<fs_key>) INDEX 1.

SPLIT iv_slug AT ',' INTO ls_attach-filename
ls_attach-ref_guid
ls_attach-obj_name.

ls_attach-mimetype = is_media_resource-mime_type.
ls_attach-erdat = sy-datum.
ls_attach-ernam = sy-uname.

 
lf_data = is_media_resource-value.

** All the attachment information needed to save the file is obtained
** Now its time to save it to database/file system. Below code does that.
CREATE OBJECT lr_attachments.
ls_attach-guid = lr_attachments->create_attachment(
exporting i_attach = ls_attach
iv_content = lf_data
).

** Return the etntity back to the caller
copy_data_to_ref( EXPORTING is_data = ls_attach
CHANGING cr_data = er_entity ).

 

Implement method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_STREAM to download the file
  method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_STREAM.
data ls_stream type ty_s_media_resource.
DATA lr_attachments TYPE REF TO zcl_ut_ui5_attachments.
DATA ls_attach TYPE zui_attachments.
DATA ls_header type ihttpnvp.
DATA lv_guid TYPE guid_32.
** Read the Key Information to obtain the file details
READ TABLE it_key_tab INTO DATA(ls_key_tab) INDEX 1.
IF sy-subrc <> 0.
RETURN.
ENDIF.
lv_guid = ls_key_tab-value.

** Once the Key for the attachment is fetched. Its time to read the content
** from database/file system wherever it is stored
CREATE OBJECT lr_attachments.
lr_attachments->read_attachment( EXPORTING i_guid = lv_guid
IMPORTING es_attach_data = ls_attach
ev_content = ls_stream-value ).

** Send back the attachment content to the caller.
ls_header-name = 'Content-Disposition'.
CONCATENATE 'attachment; filename="' ls_attach-filename '"' INTO ls_header-value.
set_header( is_header = ls_header ).
ls_stream-mime_type = ls_attach-mimetype.
copy_data_to_ref( exporting is_data = ls_stream changing cr_data = er_stream ).

endmethod.

 

Implement GET_ENTITYSET method to read all the attachment information associated to a particular document. ( RefGuid is the field that identifies all the attachments associated with it )
  method ATTACHMENTSET_GET_ENTITYSET.
DATA lv_ref_guid type guid_32.
DATA lr_attachments TYPE REF TO zcl_ut_ui5_attachments.

** Get the RefGuid value to read its associated attachments
read table it_filter_select_options INTO data(ls_filter) INDEX 1.
IF sy-subrc = 0.
READ TABLE ls_filter-select_options INTO data(ls_options)
INDEX 1.
IF sy-subrc = 0.
lv_ref_guid = ls_options-low.
ENDIF.
ENDIF.
CHECK lv_ref_guid IS NOT INITIAL.
*** Your own logic to read the attachments information.
CREATE OBJECT lr_attachments.
TRY.
lr_attachments->get_all_attachment( exporting i_ref_guid = lv_ref_guid
importing rt_attachment = DATA(lt_attach) ).

SORT lt_attach BY erdat.

** Fill up the return entity
LOOP AT lt_attach INTO DATA(ls_attach).
APPEND INITIAL LINE TO et_entityset ASSIGNING FIELD-SYMBOL(<ls_entityset>).
<ls_entityset>-filename = ls_attach-filename.
<ls_entityset>-erdat = ls_attach-erdat.
<ls_entityset>-created_by = ls_attach-created_by.
<ls_entityset>-guid = ls_attach-guid.

ENDLOOP.
CATCH ZCX_ATTACHMENT.

ENDTRY.
endmethod.

 

Front-End Implementation


This UI5 code works from UI5 version 1.90.0. We are going to implement Attachments using sap.m.upload.UploadSet UI element.

Here is the XML code for the attachments view.
<mvc:View controllerName="test.ztest.controller.View1" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m"
xmlns:core="sap.ui.core" xmlns:upload="sap.m.upload">
<Shell id="shell">
<App id="app">
<pages>
<Page id="idPage">
<upload:UploadSet id="idAttach" showIcons="true" uploadEnabled="true" terminationEnabled="true"
uploadUrl="/sap/opu/odata/sap/ZATTACHMENTS_SRV/AttachmentSet" instantUpload="true" items="{path: 'oModelAttach>/items' }"
beforeUploadStarts="onBeforeUploadStarts" uploadCompleted="onUploadComplete">
<upload:items>
<upload:UploadSetItem fileName="{oModelAttach>fileName}" visibleRemove="true" removePressed="onRemovePressed">
<upload:attributes>
<ObjectAttribute title="File Description" text="{oModelAttach>fileName}"/>
</upload:attributes>
</upload:UploadSetItem>
</upload:items>
</upload:UploadSet>
</Page>
</pages>
</App>
</Shell>
</mvc:View>

Controller code to Read the existing attachments for a document ( which is RefGuid in our case )
			this.getOwnerComponent().getModel().read("/AttachmentSet", {
filters: [new Filter("RefGuid", FilterOperator.EQ, "1234")],
success: function (oData) {
var json = new JSONModel([]);
json.items = [];

for (var i = 0; i < oData.results.length; i++) {
var item = {
Guid: oData.results[i].Guid,
fileName: oData.results[i].Filename,
meddiaType: oData.results[i].Mimetype,
url: "/sap/opu/odata/sap/ZATTACHMENTS_SRV/AttachmentSet('" + oData.results[i].Guid + "')/$value",
uploadState: "Complete",
CreatedBy: oData.results[i].CreatedBy,
Erdat: oData.results[i].Erdat,
selected: false
};
json.items.push(item);
}
this.getView().getModel("oModelAttach").setData(json);

}.bind(this),
error: function (oError) {
sap.m.MessageToast.show("Error occured reading data");
}
});

instantUpload property of UploadSet starts sending the file as soon we choose file or drag and drop on to UI element. We need to send the RefGuid ( Document number, other information if needed  ) along with the request. Here comes the use of iv_slug that we have learnt while implementing DPC_EXT. I am using a comma separated list of fields in slug.

We are making use of beforeUploadStarts event of UploadSet to pass that information.
onBeforeUploadStarts: function (oEvent) {
var oHeaderItem = oEvent.getParameter("item"),
slugVal = oHeaderItem.getFileName() + ",1234,ZSD_SAMPLES";
oHeaderItem.removeAllStatuses();
oHeaderItem.addHeaderField(new sap.ui.core.Item({
key: "slug",
text: slugVal
}));
oHeaderItem.addHeaderField(new sap.ui.core.Item({
key: "x-csrf-token",
text: this.getOwnerComponent().getModel().getSecurityToken()
}));
}

Finally, Implementing onUploadComplete event to complete the upload and setAttachmentModel to read the attachments for a particular document (RefGuid in our case)
onUploadComplete: function (oEvent) {
var oStatus = oEvent.getParameter("status"),
oItem = oEvent.getParameter("item"),
oUploadSet = this.getView().byId("idAttach");
if (oStatus && oStatus !== 201) {
oItem.setUploadState("Error");
oItem.removeAllStatuses();
} else {
oUploadSet.removeIncompleteItem(oItem);
this.setAttachmentModel();
}
},
setAttachmentModel: function () {
this.getOwnerComponent().getModel().read("/AttachmentSet", {
filters: [new Filter("RefGuid", FilterOperator.EQ, "1234")],
success: function (oData) {
var json = new JSONModel([]);
json.items = [];

for (var i = 0; i < oData.results.length; i++) {
var item = {
Guid: oData.results[i].Guid,
fileName: oData.results[i].Filename,
meddiaType: oData.results[i].Mimetype,
url: "/sap/opu/odata/sap/ZATTACHMENTS_SRV/AttachmentSet('" + oData.results[i].Guid + "')/$value",
uploadState: "Complete",
CreatedBy: oData.results[i].CreatedBy,
Erdat: oData.results[i].Erdat,
selected: false
};
json.items.push(item);
}
this.getView().getModel("oModelAttach").setData(json);
}.bind(this),
error: function (oError) {
sap.m.MessageToast.show("Error occured reading data");
}
});
}

 

Let's see how it works



You can click on upload/ drag and drop files on to the UI element to upload. You can see the status of the uploading file.



Conclusion


The key point here while building this application is to know how to pass the additional parameters to the back-end with the help of slug header parameter from the front-end and how to handle it in the back-end.

 

References


API Reference: https://sapui5.hana.ondemand.com/#/api/sap.m.upload.UploadSet

Sample in Demo site: https://sapui5.hana.ondemand.com/#/entity/sap.m.upload.UploadSet

 

Hope this blog is helpful for you. Feel free to comment/suggest, like, and share.

 
12 Comments
cuong_luc
Explorer
0 Kudos
Hi abhimanyu.lagishetti7,

Thanks for blog, I'm using Service with Vocabulary-Based Annotations, so there is no option "media" for the entity type, do you know how I can use UploadSet for my application?

Thanks & Best Regards,

Dinh Cuong Luc
Former Member
0 Kudos

Hi Abhimanyu,

Thank you sharing the blog.

Few questions-

What is the type of ZUI_ATTACHMENTS_S

and ZCL_UT_Ui5_Attachments?

Also, in the frontend, in filters why have you passed "1234". Do we call this method inside onInit?

Also, what is the "1234,ZSD_Samples"  in the slugVal? Aren't we already passing the filename there?

abhimanyu_lagishetti7
Active Contributor
0 Kudos

Hi Meenakshi,

ZCL_UT_UI5_ATTACHMENTS is a utility class that I have developed which uses structure ZUI_ATTACHMENTS_S to Upload/Delete/Read attachments.

I have used File System to save the attachments and a custom table to save the metadata like Unique Key(GUID), Reference Document ( against which the attachment is being saved ), Created By, Created On etc..

1234 is an example for reference document and ZSD_SAMPLES is logical file name where the file is stored on application server.

I hope that clears.

Thanks

abhimanyu_lagishetti7
Active Contributor
0 Kudos

HI Dinh Cuong Luc,

Apologies for the delay in response.

I have not tried this. However, You can try re-define the define method of runtime artifact *_MPC_EXT and set the entity type as Media

DATA(lo_entity_type) = model->get_entity_type( iv_entity_name = <Entity Name> ).
lo_entity_type->set_is_media( abap_true ).

Thanks

cuong_luc
Explorer
0 Kudos
Hi abhimanyu.lagishetti7,

no problem, thanks for your reply anyway, I did exactly that and it works perfectly!

 

Thanks & Regards,

Dinh Cuong Luc
0 Kudos
Hi abhimanyu.lagishetti7,

Greetings.

Thanks for your blog.

could you please post class ZCL_UT_UI5_ATTACHMENTS implementation here. I was trying out and couldnt able to proceed further.

Thank you.

Ramapavani.

 

 

 
imravi23
Member
0 Kudos
Hi abhimanyu.lagishetti7,

 

It will be helpful if you can give the ZCL_UT_UI5_ATTACHMENTS implementation here.

 

Thanks,

Ravi Rathaur

 

 
kshamata
Member
0 Kudos
Hi abhimanyu.lagishetti7,

It will be helpful if you can give the ZCL_UT_UI5_ATTACHMENTS implementation here.

 

Thanks,

Kshamata .
vyankat
Discoverer
0 Kudos

Hi abhimanyu.lagishetti7,

Could you please provide the code of class ZCL_UT_UI5_ATTACHMENTS it will be helpful .

 

Thanks,

Vyankat Jadhav.

abhimanyu_lagishetti7
Active Contributor
abhimanyu_lagishetti7
Active Contributor
0 Kudos
You can check this Source Code
Asha5
Discoverer
0 Kudos

Hi Abhimanyu,

Thank you for the blog!

I have a requirement to delete the uploaded files. As our server version is 1.71.53 there are limitations in using properties/events. I have used removePressed property inside uploadSetItem and called oData delete service inside this function.

<upload:UploadSetItem fileName="{oModelAttach>fileName}"  enabledEdit="false" mediaType="{oModelAttach>mediaType}" url="{oModelAttach>url}" 
removePressed="fnOnRemovePressed" 
visibleRemove="true" >

Now when I click on delete button, a pop up appears saying, "Are you sure to delete the file XXXX?". Before clicking on Ok/cancel buttons, the delete function is called and the file gets deleted.

Here, I am not able to get the event of Ok/Cancel buttons inside the popup "Are you sure to delete the file XXXX?"

Could you please help me here?

 

Thanks & Regards,

Ayesha

Labels in this area