Variant Management Implementation Guide (UI5)
Overview –
The variant management control allows users to load, save, and change variants. You can use variant management with filter bar. The filter settings consist of selection fields, their filter parameters, and layout, But this blog refers to a variant management that allows users to load, save, and change variants without interacting filter bar.
Biggest challenge in such implementation of variant management is to enable save button, for which i have used “currentVariantSetModified(true);”
Here is the step by step guide to implement such variants –
I have created following view to implement Variant Management.
This view has two controls
- Filter bar with two input fields and one checkbox.
- Variant management.
Variant items are bound with OData service So the data is coming from database table.
View
Below is the code to create view as shown in screenshot.
<core:View xmlns:core=“sap.ui.core” xmlns:mvc=“sap.ui.core.mvc”
xmlns:fb=“sap.ui.comp.filterbar” xmlns=“sap.m” xmlns:l=“sap.ui.layout”
xmlns:v=“sap.ui.comp.variants” controllerName=“scn.Punter”
xmlns:html=“http://www.w3.org/1999/xhtml“ >
<App id=“app”>
<Page title=“Variant Management” navButtonPress=“onNavBack” showNavButton=“true”>
<content>
<v:VariantManagement id=“vm” select=“onSelect” save=“onSave” enabled=“true” manage=“onManage”
showExecuteOnSelection=“true” showShare=“false” variantItems=“{/VariantSet}”>
<v:variantItems>
<v:VariantItem text=“{VAR_NAME}” key=“{VAR_KEY}”> </v:VariantItem>
</v:variantItems>
</v:VariantManagement>
<fb:FilterBar id=“fb” search=“onGo” initialise=“initialise”>
<fb:filterItems>
<fb:FilterItem name=“A” label=“FirstProfile”>
<fb:control>
<Input id=“firstProfile” value=“{selection>/FIRST_PROFILE}” type=“Text” placeholder=“First Profile …”
showSuggestion=“true” showValueHelp=“true” valueHelpRequest=“firstProfileValueHelp” />
</fb:control>
</fb:FilterItem>
<fb:FilterItem name=“B” label=“Second Profile”>
<fb:control>
<Input id=“secondProfile” value=“{selection>/SECOND_PROFILE}” type=“Text” placeholder=“Second Profile …”
showSuggestion=“true” showValueHelp=“true” valueHelpRequest=“secondProfileValueHelp”></Input>
</fb:control>
</fb:FilterItem>
<fb:FilterItem name=“C” >
<fb:control>
<CheckBox id=“critical” selected=“{selection>/CRITICAL}” text=“Critical” />
</fb:control>
</fb:FilterItem>
</fb:filterItems>
</fb:FilterBar>
</content>
</Page>
</App>
</core:View>
Controller
sap.ui.controller(“scn.Punter”, {
onInit : function() {
var oModel = new sap.ui.model.json.JSONModel();
oDataModel = new sap.ui.model.odata.ODataModel(“https://xxxxxx.xxx.sap.corp:xxxxx/sap/opu/odata/xxxxxx/xxxxx_xxxxxxxx_SRV/“);
oDataModel.read(“VariantSet”,null,null,true,function(oData, response){
oModel.setData({VariantSet : oData.results});
}, function(err) {
alert(“Service Failed”);
});
sap.ui.getCore().setModel(oModel);
var oModelSelection = new sap.ui.model.json.JSONModel();
oModelSelection.setDefaultBindingMode(sap.ui.model.BindingMode.OneWay);
sap.ui.getCore().setModel(oModelSelection,“selection”);
},
onSave : function(oEvent) {
jQuery.sap.require(“sap.m.MessageToast”);
var params = oEvent.getParameters();
if (params.overwrite){
//Get Values from selection screen
var parametersValue = this.getParametersValue();
//Get selected Variants Data
var selectedKey = oEvent.getSource().getSelectionKey();
var bindingPath = oEvent.getSource().getItemByKey(selectedKey).getBindingContext().getPath();
var modelData = sap.ui.getCore().byId(“idPunter1”).byId(“app”).getModel().getProperty(bindingPath);
var save = Object.create(null);
save.FIRST_PROFILE = parametersValue.firstProfile;
save.SECOND_PROFILE = parametersValue.secondProfile;
save.CRITICAL = parametersValue.critical;
save.VAR_KEY = modelData.VAR_KEY;
save.VAR_NAME = modelData.VAR_NAME;
$.extend( modelData, save );
sap.ui.getCore().byId(“idPunter1”).byId(“app”).getModel().refresh();
oDataModel.update(“VariantSet(‘”+save.VAR_KEY+“‘)”, save, null,function(oData, response){
}, function(err) {
alert(“Service Failed”);
});
}
else{
var parametersValue = this.getParametersValue();
var newEntry = Object.create(null);
newEntry.VAR_NAME = params.name;
newEntry.VAR_KEY = params.key;
newEntry.FIRST_PROFILE = parametersValue.firstProfile;
newEntry.SECOND_PROFILE = parametersValue.secondProfile;
newEntry.CRITICAL = parametersValue.critical;
//Updating database via Odata
oDataModel.create(“VariantSet”,newEntry, null,function(oData, response){
//Updating Json Model Local Data
var Data = sap.ui.getCore().byId(“idPunter1”).byId(“app”).getModel().getData().VariantSet;
Data.push(newEntry);
sap.ui.getCore().byId(“idPunter1”).byId(“app”).getModel().refresh();
}, function(err) {
alert(“Service Failed”);
});
}
var sMessage = “New Name: “ + params.name + “\nDefault: “ + params.def + “\nOverwrite:” + params.overwrite + “\nSelected Item Key: “ + params.key;
sap.m.MessageToast.show(sMessage);
},
onManage : function(oEvent) {
“use strict”;
jQuery.sap.require(“sap.m.MessageToast”);
var params = oEvent.getParameters();
var renamed = params.renamed;
var deleted = params.deleted;
//rename backend data
if (renamed){
renamed.forEach(function(rename){
oDataModel.update(“/VariantSet(‘”+rename.key+“‘)”,
{VAR_KEY: rename.key,
VAR_NAME:rename.name}, null, function(){
alert(“Update successful”);
},function(){
alert(“Update failed”);});
});
}
var sMessage = “renamed: \n”;
for (var h = 0; h < renamed.length; h++) {
sMessage += renamed[h].key + “=” + renamed[h].name + “\n”;
}
//delete backend data
if (deleted){
deleted.forEach(function(remove){ oDataModel.remove(“/VariantSet(‘”+remove+“‘)”, null, function(){
alert(“Delete successful”);
},function(){
alert(“Delete failed”);});
});
}
sMessage += “\n\ndeleted: “;
for (var f = 0; f < deleted.length; f++) {
sMessage += deleted[f] + “,”;
}
sap.m.MessageToast.show(sMessage);
},
onSelect : function(oEvent) {
var selectedKey = oEvent.getSource().getSelectionKey();
if(selectedKey === “*standard*”){
var modelData={};
var model=sap.ui.getCore().byId(“idPunter1”).byId(“app”).getModel(“selection”);
model.setData(modelData);
model.refresh();
}
else{
var bindingPath = oEvent.getSource().getItemByKey(selectedKey).getBindingContext().getPath();
var modelData=sap.ui.getCore().byId(“idPunter1”).byId(“app”).getModel().getProperty(bindingPath);
var model=sap.ui.getCore().byId(“idPunter1”).byId(“app”).getModel(“selection”);
model.setData(modelData);
if(model.oData.CRITICAL == “false” || model.oData.CRITICAL == false ){
model.oData.CRITICAL = false;
}
else
model.oData.CRITICAL = true;
model.refresh();
}
var sMessage = “New Variant Selected:”+selectedKey;
sap.m.MessageToast.show(sMessage);
},
onAfterRendering: function() {
var controlIdArray=“firstProfile secondProfile critical”.split(” “);
controlIdArray.forEach(function(controlId){
var control=sap.ui.getCore().byId(“idPunter1”).byId(controlId);
control.addEventDelegate({
onfocusout : function() {
var selectedKey = sap.ui.getCore().byId(“idPunter1”).byId(“vm”).getSelectionKey();
var bindingPath = sap.ui.getCore().byId(“idPunter1”).byId(“vm”).getItemByKey(selectedKey)&&sap.ui.getCore().byId(“idPunter1”).byId(“vm”).getItemByKey(selectedKey).getBindingContext().getPath();
var modelData=sap.ui.getCore().byId(“idPunter1”).byId(“app”).getModel().getProperty(bindingPath);
var map = {
critical : “CRITICAL”,
firstProfile : “FIRST_PROFILE”,
secondProfile : “SECOND_PROFILE”,
};
if(controlId===“critical”){
if(modelData[“CRITICAL”] !== control.getSelected()){ sap.ui.getCore().byId(“idPunter1”).byId(“vm”).currentVariantSetModified(true);
}
}else if (!modelData){
sap.ui.getCore().byId(“idPunter1”).byId(“vm”).currentVariantSetModified(true);
}
else if (modelData[map[controlId]] !== control.getValue()){ sap.ui.getCore().byId(“idPunter1”).byId(“vm”).currentVariantSetModified(true);
}
}
});
});
},
getParametersValue: function (){
var parametersValue = Object.create(null);
parametersValue.firstProfile = sap.ui.getCore().byId(“idPunter1”).byId(“firstProfile”).getValue();
parametersValue.secondProfile = sap.ui.getCore().byId(“idPunter1”).byId(“secondProfile”).getValue();
parametersValue.critical = sap.ui.getCore().byId(“idPunter1”).byId(“critical”).getSelected();
return parametersValue;
},
});
Thanks
– Tapesh Syawariya
Thanks!!!!
detailed explanation
Very well explained.
Thanks Tapesh.
69 others 🙂
Hi Tapesh,
We are trying to implement variant management in our
project.So We are referring to the code example.
We have implemented it in the same way as explained,
but while showing the variant set it is showing us only one value
but we have four variants.
The result is same in case of odata binding as well as in json binding
Please guide us on the same
Regards,
Lekhak Patil
Check your data in the model, I think it does not have keys that's why it is accepting only one value from the data.
Thanks for the blog, very helpful!
One question though:
Do you save the variants in a Z-table or is there a SAP standard possibility?
I have used Odata Service to store variant data but you can also through use Personalization fiori container using ushell.
oPersonalizationService = sap.ushell.Container.getService(
"Personalization"
)
But where do you keep the data if the user logs out?
Or do you lose all the variants after each log out?
Hi Tapesh,
How the persistence works with below service? does this call a standard services?
sap.ushell.Container.getService(
"Personalization"
)
Please clarify?
Regards,
BG
Hi,
Do you use your own OData service to store the variant?
Regards,
Serge.
Yes i have used OData service. You can store it in front end as well using ushell (fiori container).
Hi,
I would like to use the same service as the SmartFilter does 🙂 .
Is-it possible?
Regards,
Serge.
Unless you are asking for clarification/correction of some part of the Document, please create a new Discussion marked as a Question. The Comments section of a Blog (or Document) is not the right vehicle for asking questions as the results are not easily searchable. Once your issue is solved, a Discussion with the solution (and marked with Correct Answer) makes the results visible to others experiencing a similar problem. If a blog or document is related, put in a link. Read the Getting Started documents (link at the top right) including the Rules of Engagement.
NOTE: Getting the link is easy enough for both the author and Blog. Simply MouseOver the item, Right Click, and select Copy Shortcut. Paste it into your Discussion. You can also click on the url after pasting. Click on the A to expand the options and select T (on the right) to Auto-Title the url.
Thanks, Mike (Moderator)
SAP Technology RIG
Does ui5 Variant managenet act as save variants in GUI ? If i save a variant for a filter in Ui5 for user1 , can other users access it or not ?
If you are using personalization , other will not be able to see your variant
Hi Tapesh,
How the persistence works with below service? does this call a standard services?
sap.ushell.Container.getService(
"Personalization"
)
Please clarify?
Regards,
BG
persistence i have not used, It works when you are working with smart controls.
sap.ushell.Container this will work only when you run throgh fiori container, or when you try to run your application in fiori sandbox, Otherwise you will get error sap.ushell not found
Nice blog Tapesh.
We have a requirement to implement variant management where we need to save tiles as variants with selection within that gets execution on navigation.
Example: We have an Orders application with master list containing 'Filter / Grouping / Sort' options. When we try to save the variant with specific selections, a new tile should be created and on navigating to the newly created tile, the variant should be applied.
Above scenario is possible ? If yes, can you please point the steps we should follow ?
Thanks.
Hi Tapesh,
any reason why you did not use the LREP Service?
Concerning storing Variants inside AS ABAP, there is the out-of-the-box LREP services inside AS ABAP which is part of the SAPUI5 Flexibility services.
We had a customer szenario, where this services has not been available (NW 7.01) and especially for this szenario, we used the FakeLrepConnector (like seen in the samples)
and have overwritten the custom storage solution in place.
Doing it this way, we have been compatible with further updates on UI5 core.
But if you are running on an up-to-date AS ABAP, the corresponding SAP/BC/LREP service will automatically handle this for you without any additional coding.
https://help.sap.com/viewer/468a97775123488ab3345a0c48cadd8f/7.4.19/en-US/a8e55aa2f8bc4127923b20685a6d1621.html
Is your solution used in prior to LREP?
Regards Holger
Hi Holger,
I have the same requirements as in in the Guide above. I want to implement the Variant Management for my Filterbar using Lrep (flexibilty Service), but can't figure out how to get it done. I can only find examples for Smart-Elements, but im not using Smart-Elements. Is it possible that you could provide an example? I would really appreciate.
Best Regard Vura
The FakeLREP needs to be intialized like this
Hi Holger,
thank you for replying!!! I will try it the next days.
Regard Vural
Hi Tapesh -
Thank you for excellent blog -
I created a shared variant and want to make that shared variant as default variant for all other users. Also have a use case where need to have a logic to dynamically set variant based on some conditions. Is there a way to get a varinat set in OnInit() funtion in conroller.js ?
I posted a question in question in Q&A too.. But helpful no responses. Any hint is greatly appriciated.
(https://answers.sap.com/questions/447876/sapui5-set-default-variant.html?childToView=447897#answer-447897)
Thanks,
Tanveer
Hi Tanveer,
Have you done it? I want to do the same? How to implement it?
what is the advantages using this custom logic rather than using a persistence key..? Please comment..? I need to use this if it helps for my requirement..?
Hi everyone
can anyone tell me what is sap.ui.getCore().byId(“idPunter1”) in controller ?
what is idPunter1 which id is this.
Is there more than one controller ?
Hi,
we had implemented the variant management in our app, but since the upgrade to 1.71 it isn't working anymore ("unable to load the data. this can happen if you are not connected to the internet, or if underlying system or component is not available" ) . Our app is with .js views without smart table and it is a stand alone app (not running with FLP, but in EP Portal or directly on our ECC system).
how to fix this?
Thanks in advance
Vo