Technical Articles
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.
Hi Alex,
thanks for sharing. Helped me a lot to enhance SmartVariantManagement for a custom SegmentedButton.
BR, Gunnar
Hi Gunnar,
I'm glad it helped you out!
Alex
Hi, Can you please help with the code in view(xml) and below method:
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