In February I switched my job, I was a C# developer and now, I`m using SAP UI5 to create new, modern software. My main task in the past was to create or modify some client applications. My current task is, to build a seat reservation tool using UI5.
During my work on the application I learned a lot about the SAPUI5 framework. Now I would like to share my experience with you.
First I would like to give you a short overview of the application.
I have a list of four rooms in my master view at the moment (later it would be a variable amount of rooms) and every room has a detail view with two, three or four seats. Every seat has his own attributes and positions. My current program includes a detail view with an “ObjectList” control, I bind the model at this element as an“ObjectListItems”. After the event “UpdateFinished” I hide this control.
Why I go this kind of way?
Because I can`t bind my model at the tiles container in the XML view, so I don`t get an actual model. To continue my tiles story, I create a new function in the event (“UpdateFinished”) and draw the tiles. In this function I use the property ODataModel of the model. I collect all valid entries of my selected room and write them in a separate list. At the end I use a loop to create the tiles and fill them with the attributes.
In the detail.view I used an empty AbsoluteLayout as a container.
<iml:AbsoluteLayout id="AL1"></iml:AbsoluteLayout>
The controller includes the following function:
drawTiles: function(oEvent) { // prepare a list var activeList = []; if (localController == null) localController = this; // get the local model and transfer all objects in the odata object into the prepared list, // if the the condition is true var model = localController.getView().getModel(); $.each(model.oData, function(index, value) { if (index.indexOf("SeatSet")>-1) { activeList.push(value); } }); // GET IMAGE // var oImageSource = localController.getView().byId("imageBox").getSrc(); var oImageSource = pic; // save the local items and model from hided list localItems = localController.getView().byId("lineItemList").getItems(); // sort activeList and convert roomNo (string) var roomid = ZSeatReservationUI5.util.Formatter.Quantity(roomNo); activeList = this.sortList(activeList, roomid); // set ABSOLUTE LAYOUT var heigth = "800px"; var width = "650px"; var oAbsoluteLayout = localController.getView().byId("AL1"); oAbsoluteLayout.setVisible(true); oAbsoluteLayout.destroyContent(); oAbsoluteLayout.setHeight(heigth); oAbsoluteLayout.setWidth(width); oAbsoluteLayout.addContent(new sap.ui.commons.Image("Background", {src: oImageSource, width: width, heigth: heigth})); var i = 0; // loop on prepared list for every item and create for every item in list a new tile while(activeList.length > i) { var left = 0; var top = 0; var oContext = activeList[i]; // defined positions switch (i){ case 0: left = 116; top = 50; break; case 1: left = 340; top = 50; break; case 2: left = 116; top = 306; break; case 3: left = 340; top = 306; break; default: break; } left = left + "px"; top = top + "px"; var oTile = new sap.m.StandardTile(); //Layout: size of tiles // Height: 226px // Width: 194px // set the bindings of the tiles oTile.setTitle(ZSeatReservationUI5.util.Formatter.List(oContext.Attribute)); oTile.setNumber(ZSeatReservationUI5.util.Formatter.SeatText(oContext.SeatID)); oTile.setIcon(ZSeatReservationUI5.util.Formatter.UserUrl(oContext.UserId)); oTile.setInfo(ZSeatReservationUI5.util.Formatter.StateText(oContext.State)); oTile.setInfoState(ZSeatReservationUI5.util.Formatter.State(oContext.State)); oTile.setNumberUnit(oContext.User); oTile.attachPress(this.handleSelectDialogPress); oAbsoluteLayout.addContent(oTile, {left: left, top: top}); i++; } }, ,,,,,,
After this, the app looks like:
The tiles includes a press event, that triggers a reservation of the selected seat.
In addition I’m using the following ODATA structure:
I have also tested another way, the use a TileContainer control. The structure is very simple, I have created a container in my detail view.
<TileContainer xmlns="sap.m" id="idTileContainer" width="100%" height="100%" editable="" allowAdd="" tileMove="" tileDelete="" tileAdd=""> <tiles> </tiles> </TileContainer>
The controller includes the same function as the first example, except of the loop. I tried to use a template and the “bindAggregation” function of the container.
var oTileContainer = localController.getView().byId("idTileContainer"); oTileContainer.setModel(model); var oTileTemplate = new sap.m.StandardTile({ title:"{Attribute}", number: "{path:'SeatID', formatter:'ZSeatReservationUI5.util.Formatter.Quantity'}", info: "{path: 'State', formatter:'ZSeatReservationUI5.util.Formatter.StateText'}", icon: "{path: 'UserId', formatter:'ZSeatReservationUI5.util.Formatter.UserUrl'}", infoState: "{path: 'State', formatter:'ZSeatReservationUI5.util.Formatter.State'}", numberUnit: "{User}" }); oTileContainer.bindAggregation("tiles", "/SeatSet", oTileTemplate); oTileTemplate)
I ask myself the following question, why I couldn’t use the tiles and the tile container like a list control, for example, likes an objectlist with objectlistitems?
I also tried to create a tile container at the XML view . In the following I tried to bind the model, but I only get an empty page. I think the problem is, I didn’t define the aggregation like in a list control. (short example below)
<List id="lineItemList" items="{path:'SeatSet'}" mode="{device>/listMode}" select="handleSelectDialogPress" updateFinished="updateFinished" visible="true" headerText="{i18n>DETAIL_CAPTION} {path: 'RoomID', formatter: 'ZSeatReservationUI5.util.Formatter.Quantity'}"> <items> …
The detail view contains this snippet.
<TileContainer xmlns="sap.m" id="idTileContainer" width="100%" height="100%" editable="" allowAdd="" tileMove="" tileDelete="" tileAdd=""> <tiles> <StandardTile xmlns="sap.m" id="idTile" removable="true" title="{i18n>DETAIL_SEATNO} {path:'SeatID', formatter:'ZSeatReservationUI5.util.Formatter.Quantity'}" info="{path: 'State', formatter:'ZSeatReservationUI5.util.Formatter.StateText'}" icon="{path: 'UserId', formatter:'ZSeatReservationUI5.util.Formatter.UserUrl'}" activeIcon="" number="{UserId}" numberUnit="" infoState="{path: 'State', formatter:'ZSeatReservationUI5.util.Formatter.State'}" type="None" iconDensityAware="true" press=""> </StandardTile> </TileContainer>
I hope I could give you a little insight into the use of tiles. If there are any suggestions or ideas for an improvement of my app, bring it on.
Thanks.