Skip to Content
Author's profile photo Mahdi Jaberzadeh Ansari

Fixed header for UI5 Smart Table

In SAPUI5 application we often use sap.m.table instance directly or via the sap.ui.comp.smarttable.SmartTable.

One of the problems is how to keep the header toolbar and table’s header on top when we do scrolling.

In the following picture  you can see what happen when we scrolling in the worklist table which has a smart table and a sap.m.table as its including instance table.

But what we expect is to have the both custom toolbar and table’s header on top while scrolling.

 

Since version 1.54 of the SAPUI5 you can use the sticky attribute of the sap.m.table and then keep the header of the table on top. At the moment this attribute only accept 2 values.

  1. sap.m.Sticky.ColumnHeaders which only keeps the column headers in a fixed position
  2. sap.m.Sticky.None

Thus if we define a sap.m.table instance like the following:

<m:Table id="table" mode="MultiSelect" sticky="ColumnHeaders"> 
.... 
</m:Table>

Then we will have something like this when scrolling:

Fine, it is better than previous that we had no header on top. But still if user wants to use the buttons inside of the toolbar need to scroll down, then select the row(s) and then scroll up to use the buttons inside of the toolbar.

Let’s take a deeper look on what has been added to our html dom elements when we use this attribute:

Actually one css class which is called sapMListTblStickyColHdr has been added to the header of the table. And in the css part we have these:

.sapMListTblStickyColHdr, html[data-sap-ui-browser^='cr'] 
.sapMListTblStickyColHdr>.sapMTableTH {
    position: sticky;
    position: -webkit-sticky;
    top: 0;
    z-index: 100;
}

So we can use the same idea to keep the custom toolbar of our smartTable on top. Then let’s add some custom css and add a custom css class to our custom toolbar:

<smartTable:customToolbar>
	<m:OverflowToolbar id="stickyToolbar" design="Solid" class="stickyToolbar">
		<m:ToolbarSpacer/>
			<m:SearchField id="searchField" tooltip="Search" width="auto" search="onSearch" liveChange="onSearchLiveChange"/>
			<m:Button type="Transparent" press="onCreateBtnPress" icon="sap-icon://add" tooltip="Add"/>
			<m:Button type="Transparent" press="onDeleteBtnPress" icon="sap-icon://delete" tooltip="Delete"/>
	</m:OverflowToolbar>
</smartTable:customToolbar>

And the custom css which is normally placed inside of the style.css file must have:

.stickyToolbar {
    position: sticky;
    position: -webkit-sticky;
    top: 0;
    z-index: 101;
}

Please note that we assigned the z-index to 101 (one value more than what we saw in sapMListTblStickyColHdr class).

But still it does not work, and the reason is that the class has been assigned to a deeper dom element. While if we assign it to its parent all would work.

So we will use the onAfterRendering event of the smart table to assign the css class to toolbar’s parent. If you noticed, we assigned one id to our custom toolbar then we will use that id to retrieve it.

// This function must be bound to the view's afterRendering event
onAfterRendering: function() {
	// Stick the toolbar and header of the smart table to top. 
	var oSmartTable = this.byId("__smartTableWorklist");
	oSmartTable.onAfterRendering = function() {
		var oToolbar = this.byId("stickyToolbar"),
			oParent = oToolbar.$().parent();
		if (oParent) {
			oParent.addClass("stickyToolbar");
		}
	}.bind(this);	
},

As you can see in the above code we found the parent dom element of our custom toolbar. (In the previous figure it is a div with “__data28” as its id). Here is the result:

OK, not bad. But now we have another problem. We could keep the custom toolbar on top but as it is seen the header is going to be hide under the custom toolbar as soon as we scroll (The yellow highlight in the above picture). The reason is because of top property of the table’s header. Actually it will also stay on top but under the custom toolbar as it has smaller z-index. If you want to see it, just change the z-index of the stickyToolbar to some value smaller than 100. You can see the result of this change here:

Yeah, you can see now the table’s header move to places on top to 0 point in Y-axel.
Let’s return the z-index to 101 again. We have to actually set the top property of the table’s header to a value equal to the outer height of the custom toolbar in runtime.

For this, we simply remove the sticky property of the sap.m.table instance and then will generate a custom css in runtime and assign it in the afterRendering event of the table. Here are the steps:

  1. Remove the sticky property from table instance:
    <m:Table id="table" mode="MultiSelect">​
  2. Change the afterRendering method of the view like this:
    onAfterRendering: function() {
    	// Stick the toolbar and header of the smart table to top. 
    	var oSmartTable = this.byId("__smartTableWorklist");
    	oSmartTable.onAfterRendering = function() {
    		var oToolbar = this.byId("stickyToolbar"),
    		    oParent = oToolbar.$().parent();
    		if (oParent) {
    			oParent.addClass("cimtStickyToolbar");
    		}
    	}.bind(this);
            // This is new code to make the table's header also sticky
    	var oTable = this.byId("table");
    	oTable.onAfterRendering = function() {
    		oTable.addStyleClass("cimtStickyTableMSW");
    		var oToolbar = this.byId("stickyToolbar"),
    		iTop = oToolbar.$().outerHeight();
    		if ($("head").find("style#cimtStickyTableMSW").length !== 0) {
    			$("head").find("style#cimtStickyTableMSW").remove();
    		}
    		var style = $("<style id='cimtStickyTableMSW'></style>");
    		$(style).html(" .cimtStickyTableMSW > table > thead > tr," +
    			".cimtStickyTableMSW > table > thead > tr > th {" +
    			"	position: sticky;" +
    			"	position: -webkit-sticky;" +
    			"	top: " + iTop + "px;" +
    			"	z-index: 100;" +
    			"}");
    		$("head").prepend(style); //eslint-disable-line
    	}.bind(this);
    }, // end of afterRendering handler of the view. ​

As you have seen, here we added a new style element on runtime to the head tag of the page. I know it is not recommended but it is the best place to add the style tag, to be able to remove it for the next times that we need to change the top attribute based on another rendering situation (the height of the custom toolbar can be vary).

And here is the final result:

I hope you find this post useful.

Assigned Tags

      15 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Nabi Zamani
      Nabi Zamani

      Mahdi, that’s a nice one. Thanks! I hope to meet you in June…

       

      Author's profile photo Mahdi Jaberzadeh Ansari
      Mahdi Jaberzadeh Ansari
      Blog Post Author

      Thanks Nabi. I hope to.

      Author's profile photo Ivan Galimov
      Ivan Galimov

      Hi

      This is method work in Chrome, but not in IE.
      How fixed head in IE ?

      Author's profile photo Mahdi Jaberzadeh Ansari
      Mahdi Jaberzadeh Ansari
      Blog Post Author

      Hi Ivan. Thanks for the comment. You can find your answer here.

       

      Shortly the answer is:

      sticky doesn’t work on IE11, but luckily, in this case, you can use fixed, which will work on both old and new browsers.

      But please take care the suggested solution cannot work because top:0 is assumed the top of the browser and not the container div.

       

      Author's profile photo Ivan Galimov
      Ivan Galimov
      I understand, Thanks for the answer.

       

      Author's profile photo ARUSH TANEJA
      ARUSH TANEJA

      Hi,

      I am using a custom toolbar. It is getting fixed along with the table header until scrolling for 6-7 rows but is toolbar is not sticking at the top after that. Header remains fixed at the height = top + toolbar height.

      PFA screenshot.

      Author's profile photo ARUSH TANEJA
      ARUSH TANEJA

      Hello,

      Please ignore my previous issue. I found the solution. I am using sap.m.page and the overflow property was causing the issue. Putting smart table in VBox solved the issue.

      Author's profile photo Vishwa Ranjan
      Vishwa Ranjan

      Hi Arush,

      How did you overcome this? I am also facing same issue.

       

      Can you please share code?

      Author's profile photo Arpit Agrawal
      Arpit Agrawal

      Hi,

      Now sticky has multiple options like InfoToolbar, ColumnHeaders and HeaderToolbar. So if we want to header and toolbar fixed, we can simply achieve it by:

      <Table sticky="ColumnHeaders,HeaderToolbar" />

       

      Thanks,

      Arpit

      Author's profile photo Asaf Ali
      Asaf Ali

      custom toolbar can't be made sticky with HeaderToolbar

      Author's profile photo Nagandla Raghu Ram
      Nagandla Raghu Ram

      Hi,

      Can we also have Fixed footer as well. If there is Use Case, where the Customer wants to print products, if the no products exceeds come to next page- this next page should also have same fixed header and footer. Can we achieve this?

       

      Thanks and Regards,

      RR

      Author's profile photo Pavel VEREMENYUK
      Pavel VEREMENYUK

      Since ui5 version 1.56 there is property placeToolbarInTable at SmartTable which helps to achieve sticky custom toolbar while responsive table scrolling

      Author's profile photo Vinay Nandina
      Vinay Nandina

      In case if someone has declared table inside a smartTable with a customToolBar,then use placeToolbarInTable=”true” property at smartTable and sticky=”ColumnHeaders,HeaderToolbar” at inside table to make the both header and customToolBar sticky.

      Author's profile photo Navneet Kaur
      Navneet Kaur

      it worked !! Thanks

      Author's profile photo Asim Md
      Asim Md

      Among all, your solution is the best. Thanks. Exactly what i needed