Skip to Content
Technical Articles

SAPUI5 FilterBar with SmartVariantManagement

Objective

Create a custom FilterBar extension with a fully working SmartVariantManagement.

It requires minimal effort with the filters data, the rest is already implemented!

Backstory

I had a business requirement to create a custom Fiori app that should have a filter bar with variant management similar to the one from standard SAP applications.

The basic variant management for the FilterBar element (SmartVariantManagementUi2) lacks a lot of features (sharing, transport, apply automatically).

I tried using SmartFilterBar because it already has everything you need in terms of variant management. However, I stumbled upon some problems and also I did not know how to implement certain features so I decided to abandon it.

Then I have found this great blog that talks about creating a custom variant management using sap.ui.comp.variants.VariantManagement.

https://blogs.sap.com/2017/01/12/variant-management-implementation-using-shell-personalization-service/

I have also implemented all the features that the blog did not talk about. However, there are two problems, one is that the element is not IN the filter bar without maybe some workarounds, second is that the sharing (transporting) feature would be implemented manually which is not a comfortable thing to do.

Then this tutorial appeared in my searches. It talks about how to use SmartVariantManagement in the FilterBar. Unfortunately, it was not that straightforward as it says and this is what I will try to cover in this blog.

https://help.sap.com/doc/saphelp_uiaddon10/1.17/en-US/2a/e520a67c44495ab5dbc69668c47a7f/frameset.htm

Implementation

The SAPUI5 version I have worked on is 1.60.

Extend the FilterBar control

There are some modifications of the code from the FilterBar documentation above.

  1. There is not such method as addControl, use setControl
    oPersInfo.setControl(this)​;
  2. Use this._oSmartVM because there is no variable called oSmartVM.
    this._oSmartVM.addPersonalizableControl(oPersInfo);

     

  3. Overwrite the mehod _isTINAFScenario. The original one checks only with this._isUi2Mode() which verifies that the variant management is an instance of SmartVariantManagementUi2. Add a case for SmartVariantManagement.

The FilterBar.js file

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

sap.ui.define([
    "sap/ui/comp/filterbar/FilterBar",
    "sap/ui/comp/smartvariants/PersonalizableInfo",
    "sap/ui/comp/smartvariants/SmartVariantManagement"
], function (FilterBar, PersonalizableInfo, SmartVariantManagement) {
   "use strict";
   
   var CustomFilterBar = FilterBar.extend("custom.control.FilterBar", {
       renderer: function(oRm, oControl) {
           FilterBar.getMetadata().getRenderer().render(oRm, oControl);
       }
   });
   
   /**
    * Initialise variant management control
    * @private
    */
   CustomFilterBar.prototype._initializeVariantManagement = function () {
       if (this._oSmartVM && this.getPersistencyKey()) {
           var oPersInfo = new PersonalizableInfo({
               type: "filterBar",
               keyName: "persistencyKey"
           });
           oPersInfo.setControl(this);
           
           this._oSmartVM.addPersonalizableControl(oPersInfo);
           FilterBar.prototype._initializeVariantManagement.apply(this, arguments);
       } else {
           this.fireInitialise();
       }
   };
   
   /**
    * Use SmartVariantManagement instead of SmartVariantManagementUi2
    * Activate the public and apply automatically options
    * 
    * @private
    * @returns {sap.ui.comp.smartvariants.SmartVariantManagement} The variant management control
    */
   CustomFilterBar.prototype._createVariantManagement = function () {
       this._oSmartVM = new SmartVariantManagement({
           showExecuteOnSelection: true,
           showShare: true
       });
       
       return this._oSmartVM;
   };
   
   /**
    * The original method accepts only SmartVariantManagementUi2
    * 
    * @private
    * @returns {boolean} Result
    */
   FilterBar.prototype._isTINAFScenario = function() {
       if (this._oVariantManagement) {
           if (!this._isUi2Mode() && !(this._oVariantManagement instanceof SmartVariantManagement)) {
               return true;
           }
       } else {

           /* eslint-disable no-lonely-if */
           // scenario: VH dialog: VM replaced with collective search control
           if (this._oCollectiveSearch && this.getAdvancedMode()) {
               return true;
           }
           /* eslint-enable no-lonely-if */
       }

       return false;
   };
   
   return CustomFilterBar;
});

Events

By going throught the FilterBar source code, I have found that the variant management is never initialised. For this, you have to fire the filter bar’s initialise event manually which also initialises the variant management. I think it is convenient to fire it in the onAfterRendering event of the control.

this.getView().byId("filterBarId").fireInitialise();

Register the methods for fetching and applying data. I registered them after calling fireInitialise.

this.getView().byId("filterBarId").registerFetchData(this.onFetchData.bind(this));
this.getView().byId("filterBarId").registerApplyData(this.onApplyData.bind(this));

Write the registered methods

The onFetchData method should return a custom JSON with relevant data for filters.

onFetchData: function () { … }

The onApplyData method gets the above saved JSON as a parameter for the selected variant. Use this to fill the filters.

onApplyData: function (oVariantContent) { … }

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

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

Add this method for whenever the variant should be in modified state, for example in the change event of a DatePicker. In the modified state, an asterisk will appear near the title of the variant and the Save button gets enabled if it’s not the standard variant.

onFilterChange: function () {
    var oVariantManagement = this.getView().byId("filterBarId").getVariantManagement();
    
    if (oVariantManagement) {
        oVariantManagement.currentVariantSetModified(true);
    }
},

Conclusion

This control should make it easy to have a variant management in any freestyle Fiori app used in an SAP system.

I hope it helped you out!

3 Comments
You must be Logged on to comment or reply to a post.