Additional Blogs by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
remo_bettin
Explorer

Everyone knows the standard SAP Fiori "Add Button" in the right corner in the browser. But sometimes in customer projects this kind of add functionality is not beautiful or the customer has different opinion of how to design the UI. For these situations we created in a SAPUI5 application, in a bounded table with an Odata model, a new kind of visual "Add Button". In the following I want to describe this solution and hope, I can improve it with your help.

At first, the standard SAP Fiori button:

Now, this is our solution in our project and it looks like this:

We didn't create this control in the xml view, it is only based on javascript coding in the controller of the current view.


<mvc:View controllerName="sithhcategories.controller.Object" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc" xmlns:semantic="sap.m.semantic"
  xmlns:footerbar="sap.ushell.ui.footerbar">
  <semantic:FullscreenPage id="page" navButtonPress="onNavBack" showNavButton="true" title="{i18n>objectTitle}" busy="{objectView>/busy}"
  busyIndicatorDelay="{objectView>/delay}">
  <semantic:content>
  <ObjectHeader id="objectHeader" title="{Name}" number="{ID}"></ObjectHeader>
  <Table id="productList" updateFinished="onListUpdateFinished" updateStarted="onListUpdateStarted" items="{/Products}">
  <columns>
  <Column>
  <Text text="{i18n>Name}"/>
  </Column>
  <Column>
  <Text text="{i18n>Description}"/>
  </Column>
  <Column>
  <Text text="{i18n>Price}"/>
  </Column>
  </columns>
  <items>
  <ColumnListItem class="navTableItemLayout" id="masterListItem" press="onItemSelect" vAlign="Middle">
  <cells>
  <Text text="{Name}" width="20%"/>
  <Text text="{Description}" width="60%"/>
  <Text text="{path: 'Price', formatter: '.formatter.currencyValue'}" width="20%"/>
  </cells>
  </ColumnListItem>
  </items>
  </Table>
  </semantic:content>
  </semantic:FullscreenPage>
</mvc:View>

Step 1:

In the onListUpdateFinished event, we added the following coding.


onListUpdateFinished: function(oEvent) {
  // create new line "AddEntry"
  this._oTable.addItem(this._createAddLine());
  // add new line "AddEntry"
  this._addAddLine(this._oTable);
  },

Step 2:

At the beginning you create a name or id for your columnListItem control, create an id to identify the item. It is very important to do this. I will explain it later. In this method we create the columnListItem with an id and only two cells, the first cell is for the icon, the second for the text.


return BaseController.extend("sithhcategories.controller.Object", {
   formatter: formatter,
  _addColumnId: "addLineItem",
  onInit: function() {
...
...
...
...
_createAddLine: function() {
    var columnListItem = new sap.m.ColumnListItem(this._addColumnId, {
      press: [this.onLineItemPressed, this],
      type: "Active",
      vAlign: "Middle",
      cells: [
        new sap.ui.core.Icon({
        src: "sap-icon://sys-add",
        color: "#a9a9a9"
        }),
        new sap.m.Label({
          text: this._oResourceBundle.getText("addEntry")
       })
     ]});
     return columnListItem;
  },



Step 3:

In addition you have to use another method to manipulate the control, to expand the span of the second cell to the current number of columns of your table. Attention, in this case, you have to expand the cell only to number of columns (3 columns) minus one (one, because you have an icon in the first cell). So you have to expand the second cell to "2".

In this method you have to address the cell like this"", This is a very important part, this is the situation where you need the defined id (look at Step 2)!


_addAddLine: function(oTable) {
  oTable.onAfterRendering = function() {
     var $this = this.$();
     var lastlines = $this.find(".sapMLIB:nth-last-of-type(1)");
     var lastline = lastlines[0];
     var cells = lastline.getElementsByClassName("sapMListTblCell");
     try {
         cells.this._addColumnId_cell1.colSpan = 2;
      } catch (err) {
        // do nothing
      }
    };
  },

Step 4 (optional):

If you want to create an empty row in this context, you can use the following example coding.


onLineItemPressed: function(oEvent) {
  // delete "addItem" for no duplicated ids
  this._destroyAddLine();
// get a new columnListItem and a json object in an array
  this._createNewLine(oEvent, null);
// create "addItem" line
  this._oTable.addItem(this._createAddLine());
  // add "addItem" line
  this._addAddLine(this._oTable);
  },

Step 5 (optional):

You have to destroy the current "addItem" to get a free id and to delete this row in the table. Otherwise this item is not at the end of the table at the next time. To destroy the item, you have to get all items and destroy only the item with the right id (look at the id in Step 2).


_destroyAddLine: function() {
  var itemList = this._oTable.getItems();
  for (var i = 0; i < itemList.length; i++) {
    var item = itemList[i];
    if (item.getId() === this._addColumnId) {
      item.destroy();
    }
  }
},

Step 6 (optional):

Now you have to add a new columnListItem to the table. You can use the same controls as in the XML view. You can also add events, formatter functions or colors. After you create this item, you have add it to the table.


_createNewLine: function(oEvent) {
  var columnListItemNewLine = new sap.m.ColumnListItem( {
   type: sap.m.ListType.Inactive,
   unread: false,
   vAlign: "Middle",
   cells: [
     // add created controls to item
     new sap.m.Input({ type: "Text", value: "Enter name"}),
     new sap.m.Input({ type: "Text", value: "Enter description"}),
     new sap.m.Input({ type: "Text", value: "Enter price"})
     ]
  });
  this._oTable.addItem(columnListItemNewLine);
},

After you press the "AddItem", the table looks like this.

So that's it.

Possible next steps could be to extend the sap.m.table control in order to simplify the use of it.

.

3 Comments