cancel
Showing results for 
Search instead for 
Did you mean: 

How to enable sort for each column on sap.m.table?

Jayakrishnan
Active Participant
0 Kudos

Hi All,

I am working on Custom SAPUI5 application development. I have a sap.m.Table with OData Collection. I need to apply sort option for each column. When user click on the column,it should display sort descending/ascending option.

I see some example by using JSON Model, but how should i do with OData Collection?Please help me on this.

Thank you,

Regards,

JK.

Accepted Solutions (0)

Answers (2)

Answers (2)

former_member467961
Participant
0 Kudos

Hello JK,

As you mentioned, by setting the “OperationMode” on a list binding to “Client”, you can force the OData model to load alldata from the server and do sorting and filtering entirely in the browser, with no server roundtrip. Useful only when it is guaranteed that the count of data elements is low.

After the table rows binding code where you passed filters and operation mode as Server, can you try something like this:

var oTable = this.getView().byId("oTable");    
var oRowsBinding = oTable.getBinding("rows");
oRowsBinding.attachDataReceived(function(oEvent){          //Hits when the data is received from back-end server
     var oSource = oEvent.getSource();
     oSource.bClientOperation = true;
     oSource.sOperationMode = "Client";
});

//do sorting as usual

Alternative would be to use JSON Model instead of OData Model.

Jayakrishnan
Active Participant
0 Kudos

Oh Great, i will try this.

former_member467961
Participant
0 Kudos

Hello JK,

you can create column events popup for sap.m.Table by following this blogpost:

https://blogs.sap.com/2016/08/22/responsive-sapm-table-on-click-column-sort-filter/

You can replace the fragment provided as example in the blogpost with this:

columnevents.fragment.xml

<core:FragmentDefinition

xmlns:core="sap.ui.core"

xmlns="sap.ui.unified"

xmlns:m="sap.m">

	<Menu>

		<items>

			<MenuItem text="Sort Ascending" icon="sap-icon://sort-ascending" select="onAscending"/>

			<MenuItem text="Sort Descending" icon="sap-icon://sort-descending" select="onDescending"/>

            <MenuTextFieldItem

				label="Filter"

				enabled="true"

				startsSection="true"

				icon="sap-icon://filter"

				select="handleColFilterPress" />

			<MenuItem text="Clear Filter" visible="false" icon="sap-icon://clear-filter" select="clearColFilter"/>			

		</items>

	</Menu>

</core:FragmentDefinition>

Then update your controller to include sorting logic as follows:

		onAscending: function() {
			var table = this.getView.byId("table");

			var oItems = table.getBinding("items");

			var oBindingPath = table.getModel().getProperty("/bindingValue");

			var oSorter = new Sorter(oBindingPath);

			oItems.sort(oSorter);
			
			//close the column events popup
			this._oResponsivePopover.close();

		},

		

		onDescending: function() {
			var table = this.getView.byId("table");

			var oItems = table.getBinding("items");

			var oBindingPath = table.getModel().getProperty("/bindingValue");

			var oSorter = new Sorter(oBindingPath, true);

			oItems.sort(oSorter);

                        //close the column events popup
			this._oResponsivePopover.close();

        },

Don't forget to import module to controller: "sap/ui/model/Sorter".
Hope this helps!

Kind Regards,

Bopanna

Jayakrishnan
Active Participant
0 Kudos

Thank you Bopanna, I will try rhis

Jayakrishnan
Active Participant
0 Kudos

Hi Bopanna,

I am Facing below error. I changed the fragment file. after that i did not change anything in the controller.

Jayakrishnan
Active Participant
0 Kudos

This is my Detail.controller.js code:

sap.ui.define([
	"com/hex/ztraining02/controller/Basecontroller",
	"sap/ui/model/Filter",
	"sap/ui/model/json/JSONModel",
	"sap/ui/model/Sorter"
], function (Basecontroller, Filter, JSONModel, Sorter) {
	"use strict";
	var that;


	return Basecontroller.extend("com.hex.ztraining02.controller.Detail", {


		/**
		 * Called when a controller is instantiated and its View controls (if available) are already created.
		 * Can be used to modify the View before it is displayed, to bind event handlers and do other one-time initialization.
		 * @memberOf com.hex.ztraining02.view.Detail
		 */


		onInit: function () {
			var oRouter = this.getRouter();
			oRouter.getRoute("detail").attachMatched(this._onRouteMatched, this);
			that = this;
			if (!this._oResponsivePopover) {
				this._oResponsivePopover = sap.ui.xmlfragment("com.hex.ztraining02.util.Popover", this);
				this._oResponsivePopover.setModel(this.getView().getModel());
			}
			var oTable = this.getView().byId("idProductsTable");
			oTable.addEventDelegate({
				onAfterRendering: function () {
					var oHeader = this.$().find('.sapMListTblHeaderCell'); //Get hold of table header elements
					for (var i = 0; i < oHeader.length; i++) {
						var oID = oHeader[i].id;
						that.onClick(oID);
					}
				}
			}, oTable);


		},
		_onBindingChange: function (oEvent) {
			// No data for the binding
			if (!this.getView().getBindingContext()) {
				this.getRouter().getTargets().display("notFound");
			}
		},
		_onRouteMatched: function (oEvent) {
			var oView = this.getView();
			var oArgs = oEvent.getParameter("arguments");
			oView.bindElement({
				path: "/WOheaderSet('" + oArgs.key + "')", //WorkOrderHeaderSet('4000000')
				events: {
					change: this._onBindingChange.bind(this),
					dataRequested: function () {
						oView.setBusy(true);
					},
					dataReceived: function () {
						oView.setBusy(false);
					}
				}
			});


		},
		onClick: function (oID) {
			var that = this;
			$('#' + oID).click(function (oEvent) { //Attach Table Header Element Event
				var oTarget = oEvent.currentTarget; //Get hold of Header Element
				var oLabelText = oTarget.childNodes[0].textContent; //Get Column Header text
				var oIndex = oTarget.id.slice(-1); //Get the column Index
				var oView = that.getView();
				var oTable = oView.byId("idProductsTable");
				var oModel = oTable.getModel().getProperty("WorkOrderItemSet"); //Get Hold of Table Model Values
				var oKeys = Object.keys(oModel[0]); //Get Hold of Model Keys to filter the value
				oView.getModel().setProperty("/bindingValue", oKeys[oIndex]); //Save the key value to property
				that._oResponsivePopover.openBy(oTarget);
			});
		},
		onChange: function (oEvent) {
			var oValue = oEvent.getParameter("value");
			var oMultipleValues = oValue.split(",");
			var oTable = this.getView().byId("idProductsTable");
			var oBindingPath = this.getView().getModel().getProperty("/bindingValue"); //Get Hold of Model Key value that was saved
			var aFilters = [];
			for (var i = 0; i < oMultipleValues.length; i++) {
				var oFilter = new Filter(oBindingPath, "Contains", oMultipleValues[i]);
				aFilters.push(oFilter);
			}
			var oItems = oTable.getBinding("items");
			oItems.filter(aFilters, "Application");
			this._oResponsivePopover.close();
		},
		onAscending: function () {
			var oTable = this.getView().byId("idProductsTable");
			var oItems = oTable.getBinding("items");
			var oBindingPath = this.getView().getModel().getProperty("/bindingValue");
			var oSorter = new Sorter(oBindingPath);
			oItems.sort(oSorter);
			this._oResponsivePopover.close();
		},


		onDescending: function () {
			var oTable = this.getView().byId("idProductsTable");
			var oItems = oTable.getBinding("items");
			var oBindingPath = this.getView().getModel().getProperty("/bindingValue");
			var oSorter = new Sorter(oBindingPath, true);
			oItems.sort(oSorter);
			this._oResponsivePopover.close();
		},


		onListItemPress: function (oEvent) {
			var oCtx = oEvent.getSource().getBindingContext();
			var aufnr = oCtx.getProperty("Aufnr");
			var posnr = oCtx.getProperty("Posnr");


			this.getRouter().navTo("itemdetail", {
				key: aufnr,
				key1: posnr
			});
		},
		onOpen: function (oEvent) {
			//On Popover open focus on Input control
			var oPopover = sap.ui.getCore().byId(oEvent.getParameter("id"));
			var oPopoverContent = oPopover.getContent()[0];
			var oCustomListItem = oPopoverContent.getItems()[2];
			var oCustomContent = oCustomListItem.getContent()[0];
			var oInput = oCustomContent.getItems()[1];
			oInput.focus();
			oInput.$().find('.sapMInputBaseInner')[0].select();
		}


		/**
		 * Similar to onAfterRendering, but this hook is invoked before the controller's View is re-rendered
		 * (NOT before the first rendering! onInit() is used for that one!).
		 * @memberOf com.hex.ztraining02.view.Detail
		 */
		//	onBeforeRendering: function() {
		//
		//	},


		/**
		 * Called when the View has been rendered (so its HTML is part of the document). Post-rendering manipulations of the HTML could be done here.
		 * This hook is the same one that SAPUI5 controls get after being rendered.
		 * @memberOf com.hex.ztraining02.view.Detail
		 */
		//	onAfterRendering: function() {
		//
		//	},


		/**
		 * Called when the Controller is destroyed. Use this one to free resources and finalize activities.
		 * @memberOf com.hex.ztraining02.view.Detail
		 */
		//	onExit: function() {
		//
		//	}


	});


});

Jayakrishnan
Active Participant
0 Kudos

Hey I got it. But the problem is i am maintaining the OData Model Operation mode is Server. So i cannot do the sorting directly on the UI. If i maintain it in client , i can. but is only option i need to write the sorting logic in Gateway?