Skip to Content
Technical Articles
Author's profile photo Alex Necula

SAPUI5 Table with SmartVariantManagement

Objective

Add Smart Variant Management mechanism to an SAPUI5 non-smart table (sap.ui.table, sap.m.table etc.).

For a guide regarding FilterBar (sap.ui.comp.filterbar.FilterBar) please read my other blog post:

https://blogs.sap.com/2020/07/20/sapui5-filterbar-with-smartvariantmanagement

Backstory

The business requirement was to use the same features of a SmartTable variant management with a basic table.

The solution approached in this blog uses sap.ui.comp.smartvariants.SmartVariantManagement which needs minimal implementation effort.

Implementation

The SAPUI5 version I have worked on is 1.60. The control extended for this tutorial is TreeTable but you can use whatever fits your case.

The TreeTable.js file

Use this the same way you would use the standard TreeTable by including the xml namespace for custom.control.

sap.ui.define([
	"sap/ui/table/TreeTable",
	"sap/base/Log"
], function (TreeTable, Log) {
	"use strict";

	var CustomTreeTable = TreeTable.extend("custom.control.controller.TreeTable", {
		renderer: function (oRm, oControl) {
			TreeTable.getMetadata().getRenderer().render(oRm, oControl);
		},

		metadata: {
			properties: {
				/**
				 * Key used to access personalization data.
				 */
				persistencyKey: {
					type: "string",
					group: "Misc",
					defaultValue: ""
				}
			}
		}
	});

	/**
	 * Registration of a callback function. The provided callback function is executed
	 * when saving a variant is triggered and must provide all relevant fields and values in JSON.
	 * @public
	 * @param {function} fCallBack Called when a variant must be fetched
	 * @returns {sap.ui.table.TreeTable} Reference to this in order to allow method chaining.
	 */
	CustomTreeTable.prototype.registerFetchData = function (fCallBack) {

		this._fRegisteredFetchData = fCallBack;

		return this;
	};

	/**
	 * Registration of a callback function. The provided callback function is executed
	 * when a variant must be applied.
	 * The callback function will receive the corresponding data set containing all relevant data in JSON,
	 * as initially provided by the callback for fetchData.
	 * @public
	 * @param {function} fCallBack Called when a variant must be applied
	 * @returns {sap.ui.table.TreeTable} Reference to this in order to allow method chaining.
	 */
	CustomTreeTable.prototype.registerApplyData = function (fCallBack) {

		this._fRegisteredApplyData = fCallBack;

		return this;
	};

	/**
	 * Creates and returns the variant representation.
	 * @returns {object} JSON object
	 * @public
	 */
	CustomTreeTable.prototype.fetchVariant = function () {
		if (this._fRegisteredFetchData) {
			try {
				return this._fRegisteredFetchData();
			} catch (ex) {
			    Log.error("callback for fetching data throws an exception");
			}
		} else {
			Log.warning("no callback for fetch data supplied");
		}

		return {};
	};

	/**
	 * Triggers the registered callBack for applying the variant data.
	 * @private
	 * @param {object} oVariant the data blob representing part of the variant content
	 * @returns {object} data to be stored as part of the variant content
	 */
	CustomTreeTable.prototype.applyVariant = function (oVariant) {

		if (this._fRegisteredApplyData) {
			try {
				return this._fRegisteredApplyData(oVariant);
			} catch (ex) {
				Log.error("callback for applying data throws an exception");
			}
		} else {
			Log.warning("no callback for appy data supplied");
		}

		return null;
	};

	return CustomTreeTable;
});

In the onAfterRendering event, create a personalizable info of type table and append it to the table object. This links the variant management to the control.

var oPersInfo = new PersonalizableInfo({
	keyName: "id",
	type: "table"
});

oPersInfo.setControl(this._oTable);
this._oSmartVariantManagement.addPersonalizableControl(oPersInfo);

Events

Still in the onAfterRendering event of the controller, initialise the variant management and attach the handlers for fetchData and appendData. You will have to create these handlers. On the initialising event, the variant management is set as not modified.

this._oSmartVariantManagement.initialise(function () {
	this._oSmartVariantManagement.currentVariantSetModified(false);
}.bind(this), this._oTable);

this._oTable.registerFetchData(this.onTableFetchData.bind(this));
this._oTable.registerApplyData(this.onTableApplyData.bind(this));

Write the registered methods

The onTableFetchData method should return a custom JSON with relevant data for the table (for example column configuration, sorters, filters or grouping).

onTableFetchData: function () { … }

The onTableApplyData method gets the above saved JSON as a parameter for the selected variant. Use this to modify the table.

onTableApplyData: function (oVariantContent) { … }

These two methods are the only things you have to implement based on your use case.

The options Set As Default, Public (sharing with transports included), Apply Automatically, Add as Favorite, Delete, Rename should work out of the box.

Dirty State

If you implement the P13n features (like grouping), you will most likely want to be able to save the variant after the OK button of the dialog is pressed. You can do this by adding this line to the ok event.

this._oSmartVariantManagement.currentVariantSetModified(true);

Conclusion

This control should be implemented by default for any table in your future freestyle SAP Fiori apps as it has very little drawbacks (time of implementation) and many advantages.

Assigned Tags

      4 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Gunnar Lehker
      Gunnar Lehker

      Hi Alex,

      thanks for sharing. Helped me a lot to enhance SmartVariantManagement for a custom SegmentedButton.

      BR, Gunnar

      Author's profile photo Alex Necula
      Alex Necula
      Blog Post Author

      Hi Gunnar,

      I'm glad it helped you out!

      Alex

      Author's profile photo Pranav Chaudhary
      Pranav Chaudhary

      Hi, Can you please help with the code in view(xml) and below method:

      onTableFetchData

       

      onTableApplyData
      Author's profile photo Alex Necula
      Alex Necula

      Hi,

      Please see my response to Cristian Daniel De La Sota in the other blog. The idea is the same except that instead of managing filters, you have to manage the table here.

      For the xml you can look up in the same blog for my response to Emil Julenyi or searching on how to use a custom control in SAPUI5. You should find plenty of links for that.

      Alex