SAPUI5 UploadCollection Example

You are here:
← All Topics

Das SAPUI5-Framework bietet eine einfach zu implementierende Downloadmöglichkeit für Media-Entities eines OData-Services. Dazu kommt die UploadCollection zum Einsatz. Diese wird in Form der Klasse sap.m.UploadCollection ausgeliefert.

Voraussetzungen:

  1. Ein korrekt eingerichteter OData-Service mit einer Media-Entiy.
  2. Redefinition und korrekte Neu-Implementierung der GET_STREAM, (CREATE_STREAM für Upload) und DEFINE-Methode der Provider-Klassen.
  3. UI5-Version des Beispiels: 1.76

Media-Entity

Angenommen wir haben folgenden Aufbau unserer Media-Entity in ODataV2.

<EntityType Name="Document" m:HasStream="true" sap:content-version="1">
<Key>
<PropertyRef Name="ID"/>
</Key>
<Property Name="ID" Type="Edm.String" Nullable="false" MaxLength="32" sap:unicode="false" sap:label="ID" sap:creatable="false" sap:updatable="false"/>
<Property Name="DocumentName" Type="Edm.String" Nullable="false" MaxLength="254" sap:unicode="false" sap:label="Document Name"/>
<Property Name="DocumentType" Type="Edm.String" Nullable="false" MaxLength="128" sap:unicode="false" sap:label="Document Type"/>
<Property Name="Content" Type="Edm.String" Nullable="false" sap:unicode="false" sap:label="Content"/>
<Property Name="ArchivId" Type="Edm.String" Nullable="false" MaxLength="2" sap:unicode="false" sap:label="Archiv ID"/>
<Property Name="ArchivDocId" Type="Edm.String" Nullable="false" MaxLength="40" sap:unicode="false" sap:label="Archiv Document ID"/>
<Property Name="ArchivDocType" Type="Edm.String" Nullable="false" MaxLength="20" sap:unicode="false" sap:label="Archiv Document Typ"/></EntityType>
			

Die Voraussetzung bei dieser MediaEntity ist, dass die GET_STREAM-, CREATE_STREAM– und die DEFINE-Methode redefiniert und korrekt implementiert wurden.

Nun möchten wir eine Funktionalität in unsere Applikation einbauen, um die Dokumente aus dem DocumentSet zu downloaden und anzuzeigen. Um dies zu bewerkstelligen, benötigen wir das sap.m.UploadCollection-Control.

View-Implementierung

Zunächst muss die UploadCollection samt dazugehörigen UploadCollectionItems implementiert werden.

<UploadCollection id="detail_uploadcollection" items="{fileModel>/files}" mode="MultiSelect" uploadEnabled="false"						uploadButtonInvisible="true" selectionChange="onDocumnetSelectionChange">						<toolbar>
    <OverflowToolbar>
        <ToolbarSpacer/>
        <Button enabled="{viewModel>/downloadEnabled}" text="{i18n>btn_download}" press="onDownloadDocuments" type="Transparent"/>
        <UploadCollectionToolbarPlaceholder/>
        </OverflowToolbar>
</toolbar>
<items>
    <UploadCollectionItem documentId="{ID}" url="{path: 'ID', formatter: '.formatUrl'}" fileName="{DocumentName}" mimeType="{DocumentType}" enableEdit="false" enableDelete="false" visibleDelete="false" visibleEdit="false"/>
</items>
</UploadCollection>

Das UploadCollectionItem hat die Property „url„. Diese Property muss mit einer validen URL befüllt werden. In unserem Fall nehmen wir uns die aktuelle, auf den Service bezogene URL des Dokuments. Diese steht nicht direkt als Property in unserer Entiy, sondern muss über einen Umweg ausgelesen werden.

Wir behelfen uns hier mit einem Custom-Formatter, um die korrekte und valide URL unserer Media-Entity aufzulösen.

Eine valide URL, die auf den Steam unserer Media-Entity zeigt, wäre zum Beispiel:
https://<hostname>:<port>/sap/opu/odata/<servicename>/DocumentSet(ID=’566F112400211EDA9CD176726FCF0230′)/$value

Und genau diese URL möchten wir per Aggregation-Binding passend für jedes Dokument in die UploadCollection bekommen. Denn mit dem URL-Parameter „$value“ bekommen wir den Media-Stream unseres Dokuments.

Controller-Implementierung

Im Controller brauchen wir zunächst eine Formatter-Funktion, die bei jedem Binding auf die „url„-Property aufgerufen wird. In dieser Funktion holen wir uns die Service-Url des OData-Services, hängen unseren Schlüssel an und zusätzlich den „$value„-Parameter.

formatUrl: function (sSrId, sSeqnr) {
			let sUrl = this.getModel().sServiceUrl;

			sUrl += "/" + this.getModel().createKey("DocumentSet", {
				ID: sSrId
			});

			sUrl += "/$value";

			return sUrl;
		},

Nachdem wir nun das Code-Snippets implementiert haben, bekommen wir schon Items in unserer UploadCollection richtig angezeigt.

Würden wir jetzt auf ein Dokument klicken, würde in einem neuen Tab das Dokument geladen.

Wir möchten aber Dokumente selektieren und per Button downloaden. Hierfür bietet die UploadCollection die passende Funktion „downloadItem„.

Zuerst definieren wir den Eventhandler für das selectionChanged-Event der UploadCollection, um den Download-Button ein/auszublenden wenn wir Items selektieren. Die Sichtbarkeit wird über ein JSONModel namens ViewModel und der Property „downloadEnabled“ gesteuert.

onDocumnetSelectionChange: function (oEvent) {
			let oUploadCollection = oEvent.getSource();
			if (oUploadCollection.getSelectedItems().length > 0) {
				this._oViewModel.setProperty("/downloadEnabled", true);
			} else {
				this._oViewModel.setProperty("/downloadEnabled", true);
			}
		},

Anschließend wird noch der Eventhandler für das press-Event des Buttons benötigt. Hier werden die selektierten Items heruntergeladen.

onDownloadDocuments: function (oEvent) {
			let oUploadCollection = this.getView().byId("detail_uploadcollection"),
				aSelectedItems = oUploadCollection.getSelectedItems();
			for (var i = 0; i < aSelectedItems.length; i++) {
				oUploadCollection.downloadItem(aSelectedItems[i], true);
			}
		},

Anschließend können wir die Applikation ins ABAP-Backend deployen.

Nun können wir die selektierten Dokumente per Button-Press herunterladen und anzeigen. Hierfür nimmt sich die UploadCollection die Property „url“ des jeweiligen UploadCollectionItems um eine Download-URL zu definieren.

Wir sehen also, das UI5-Framework bietet hier schon einen leichten Weg, um den Dokumentendownload zu ermöglichen. Die Voraussetzung hierfür ist jedoch die richtige Implementierung des Backends und des OData-Services. Wenn dies jedoch sauber gemacht wurde, steht unserem Dokumentendownload nichts im Weg.