Technical Articles
Dynamic Response from Chatbot using Factory function in SAPUI5 [ Aggregation Binding ]
There are 4 types of Binding in SAPUI5. Let’s check one of them known as “Aggregation Binding” and how it can be implemented using Factory function for changing parameters run-time.
Lets take an example of chatbots, They are very common nowadays. Even SAP itself has a standard offering known as Conversation AI.
Generally, format of Query is fixed while Response of the bot can have different format depending upon the query.
On right hand side, User Query contains 1. Question
On left hand side, Response can have one of the multiple formats.
1. Simple answer template for QnA type of Query.
Simple Response asking for next input
2. Complex Action template involving button or multiple choices or Adaptive card for filling up a form.
Options in form of Buttons for user to click
Lets build such solution using sap.m.List libray.
SAPUI5 is following MVC architecture. There are 3 basic components – View, Controller and Model
Lets see them one by one
** XML Views and Fragments
1. main view with Control : sap.m.List
List is an iterator. It iterates over a construct and generates clones of it.
we can modify this behavior by introducing multiple constructs and provide a logic to choose which one of them to use based on data we receive from Backend ( OData or other API )
So, here add as many fragments as you want and implement Factory ( here : “queryOrRespone” ) JS code in Controlle.r
<List id="id_List" items="{path:'/listModel', factory:'.queryOrResponse'}" noDataText="Start Chatting with me">
<dependents>
<core:Fragment fragmentName="sapui101sapui101.view.query" type="XML"/>
<core:Fragment fragmentName="sapui101sapui101.view.response" type="XML"/>
</dependents>
</List>
2. Query.fragment.xml would look like below
<core:FragmentDefinition xmlns:core="sap.ui.core" xmlns="sap.m">
<CustomListItem id="id_query_item" class="query">
<HBox>
<core:Icon class="sapUiSmallMargin" size="1rem" src="sap-icon://attachment-photo"/>
<VBox class="sapUiTinyMarginBegin sapUiSmallMarginTopBottom">
<Text text="{text}"/>
<!--<Label text="{ProductId}"/>-->
</VBox>
</HBox>
</CustomListItem>
</core:FragmentDefinition>
3. Response.fragment.xml would look like below.
<core:FragmentDefinition xmlns:core="sap.ui.core" xmlns="sap.m">
<CustomListItem id="id_response_item" class="response">
</CustomListItem>
</core:FragmentDefinition>
** JS Controller .
queryOrResponse: function(sId, oContext) {
var oListItem;
var sType = oContext.getProperty("type");
if (sType === "query") {
oListItem = this.byId("id_query_item").clone();
} else if (sType === "response") {
oListItem = this.byId("id_response_item").clone();
var oContent = oContext.getObject("content");
var sViewType = oContext.getProperty("view");
var formatType = oContent.type;
var oHBox = new sap.m.HBox();
var oSubContent;
if (sViewType === "Basic") {
if (formatType === "Button") {
for (var i = 0; i < oContent.value.length; i++) {
oSubContent = new sap.m.Button({
text: oContent.value[i].text
});
if (i != 0) {
oSubContent.addStyleClass("sapUiTinyMarginBegin");
}
oHBox.addItem(oSubContent);
}
} else if (formatType === "List") {
var oComboBox = new sap.m.ComboBox();
for (var i = 0; i < oContent.value.length; i++) {
oSubContent = new sap.ui.core.Item({
text: oContent.value[i].text,
key: oContent.value[i].text
});
oComboBox.addItem(oSubContent);
}
oHBox.addItem(oComboBox);
} else if (formatType === "File") {
oSubContent = new sap.ui.unified.FileUploader({
fileType: oContent.value.type
});
var oButton = new sap.m.Button({
text: "Upload File",
press: "onFileUpload"
});
oButton.addStyleClass("sapUiTinyMarginBegin");
oHBox.addItem(oSubContent);
oHBox.addItem(oButton);
}
var oHBoxStatic = new sap.m.HBox();
var oVBoxStatic = new sap.m.VBox();
var oIcon = new sap.ui.core.Icon({
src: "sap-icon://customer",
size: "3rem"
});
oIcon.addStyleClass("sapUiTinyMargin");
var oFormattedText = new sap.m.FormattedText({
convertLinksToAnchorTags: sap.m.LinkConversion.All,
htmlText: "{text}"
});
oFormattedText.addStyleClass("sapUiTinyMarginTop");
oVBoxStatic.addItem(oFormattedText); //header
oVBoxStatic.addItem(oHBox); //content-control
oVBoxStatic.addStyleClass("sapUiTinyMargin");
oHBoxStatic.addItem(oIcon);
oHBoxStatic.addItem(oVBoxStatic);
oListItem.addContent(oHBox);
}
return oListItem;
}
** Model : JSON Response ( from API built on Django with NLP and ML to classify user intent )
jsonObj = {
"text": "Are you willing to relocate?",
"type": "response",
"view": "Basic",
"content": {
"type": "Button",
"value": [{
"text": "Yes"
}, {
"text": "No"
}]
}
}
Thank you for reading this entire blog, I think this blog must have been helpful to those who are working on SAPUI5.
So here we created how to use Factory function to generate different views based on data we receive from Model ( Backend )
I had a peculiar requirement of developing chatbot in SAPUI5 OData and using HANA features. Adaptive card was inspired by Azure Bot service which I developed in C# Bot Framework and connected via OData to SAP. In my next blog, I will write about the same.