How to dynamically bind items of sap.m.Select - sapui5

In a table, there is a drop-down for each row.
And every row has unique ID and based on it the values should be populated on UI
ID Country
1 India/Malasia/UK
2 Paris/spain/USA
3 Canada/Chile/China
So, I am trying to send the path of ObjectID.
The below code doesn't work. Not sure how to achieve this.
oEditTemplate = new Select({
forceSelection: false,
selectedKey: sPath,
items: {
path: {
path: "tempModel>ObjectId",
formatter: this._editableFormatter.bind(this, sName)
},
templateShareable: false,
template: new ListItem({
key: "{tempModel>value}",
text: "{tempModel>value}"
})
}
});

You can achieve it by using custom data and onAfterRendering. You can refer this JSBIN example
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>
<script src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-libs="sap.ui.table,sap.m"
data-sap-ui-xx-bindingSyntax="complex"
data-sap-ui-theme="sap_bluecrystal"></script>
<script>
var ITEMS = {
"1": ["India", "Malasia", "UK"],
"2": ["Paris", "Spain", "USA"],
"3": ["Canada", "Chile", "China"]
};
sap.m.Select.extend("CustomSelect", {
metadata: {
properties: {
countryId: "string"
}
},
renderer: {}
});
var oSelect = new sap.m.Select({
customData: {
key: "countryId",
value: "{ID}"
}
});
oSelect.addEventDelegate({
onAfterRendering: function(oEvent) {
var src = oEvent.srcControl;
var countryId = src.data("countryId");
if (!!countryId && src.getItems().length === 0) {
ITEMS[countryId].forEach(function(i) {
src.addItem(new sap.ui.core.Item({
text: i,
value: i
}));
});
}
}
});
var oTable = new sap.ui.table.Table({
rows: '{/d/results}',
columns: [
new sap.ui.table.Column({
label: new sap.m.Label({text: "ID"}),
template: new sap.m.Text({text:"{ID}"}),
filterProperty: 'District'
}),
new sap.ui.table.Column({
label: new sap.m.Label({text: "Country"}),
template: oSelect
})]
});
var model = new sap.ui.model.json.JSONModel({
d: {
results: [
{ ID: "1"},
{ ID: "2"}
]
}
});
oTable.setModel(model);
oTable.placeAt('content');
</script>
</head>
<body id="content" class="sapUiBody sapUiSizeCompact">
</body>
</html>

Related

How Side Navigation component can be used in UI5 to show the content?

I am trying to use Side Navigation component in UI5. From the below picture you can see a modal dialog, I have used side navigation to get the items in the left. when ever I select something from the list, corresponding content should be visible on the right.
Can someone please suggest me on how it can be achieved.
You will need some form of Splitter e.g. sap.ui.layout.Splitter
Take a look a this little Demo
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta http-equiv="Content-Type" content="text/html"/>
<meta charset="UTF-8">
<script src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js" id="sap-ui-bootstrap" data-sap-ui-libs="sap.m,sap.ui.layout" data-sap-ui-theme="sap_belize"></script>
<script>
var dialogModel = {
RateCategory_ID: {
id: "RateCategory_ID",
label: "Rate Category",
type: "MultiSelect",
values: [{
key: "ST",
value: "ST",
selected: true
}, {
key: "DT",
value: "DT",
selected: false
}]
},
Approval_Filter: {
id: "Approval_Filter",
label: "ApprovalFilter",
type: "SingleSelect",
values: [{
key: "Separate_Filter",
value: "Separate",
selected: true,
}, {
key: "Last_Approval_Filter",
value: "Last Approval",
selected: false
}]
}
};
var model = new sap.ui.model.json.JSONModel();
model.setData(dialogModel);
var oParentList = new sap.m.List({
mode: "SingleSelectMaster",
items: {
path: "/",
template: new sap.m.StandardListItem({
type: "Active",
title: "{label}"
})
},
selectionChange: function(event) {
var oBindingContext = event.getSource().getSelectedItem().getBindingContext();
oMembersList.setBindingContext(oBindingContext);
oSelectedItemsList.setBindingContext(oBindingContext);
oSelectedItemsList.getBinding("items").filter(new sap.ui.model.Filter("selected",sap.ui.model.FilterOperator.EQ,true));
}
});
oParentList.addEventDelegate({
onAfterRendering: function() {
// check if nothing is selected
if (this.getSelectedItem() === null) {
var items = this.getItems();
// check if there are items
if (items && items.length > 0) {
this.setSelectedItem(items[0], true);
}
}
this.fireSelectionChange();
}
}, oParentList);
var oMembersList = new sap.m.List({
mode: "{type}",
includeItemInSelection: true,
modeAnimationOn: false,
items: {
path: "values",
template: new sap.m.StandardListItem({
type: "Active",
title: "{value}",
selected: "{selected}"
})
},
selectionChange: function(event) {
var oBindingContext = event.getSource().getBindingContext();
oSelectedItemsList.setBindingContext(oBindingContext);
oSelectedItemsList.getBinding("items").filter(new sap.ui.model.Filter("selected",sap.ui.model.FilterOperator.EQ,true));
}
});
var oSelectedItemsList = new sap.m.List({
mode: "Delete",
modeAnimationOn: false,
visible: {
path: "type",
formatter: function(type) {
return type === "MultiSelect";
}
},
items: {
path: "values",
template: new sap.m.StandardListItem({
title: "{value}",
})
},
delete: function(oEvent) {
model.setProperty(oEvent.getParameters().listItem.getBindingContextPath() + "/selected", false);
oMembersList.fireSelectionChange();
}
});
var variablesVBox = new sap.m.VBox({
items: [
new sap.m.Label({
text: "Variables"
}),
new sap.m.Label({
text: ""
}),
oParentList
],
layoutData: new sap.ui.layout.SplitterLayoutData({
resizable: false
})
});
var membersVBox = new sap.m.VBox({
items: [
new sap.m.Label({
text: "Available Members"
}),
new sap.m.Label({text: ""}),
oMembersList
],
layoutData: new sap.ui.layout.SplitterLayoutData({
resizable: false
})
});
var selectedMembersVBox = new sap.m.VBox({
items: [
new sap.m.Label({
text: "Selected Members"
}),
new sap.m.Label({text: ""}),
oSelectedItemsList
],
layoutData: new sap.ui.layout.SplitterLayoutData({
resizable: false
})
});
var splitter = new sap.ui.layout.Splitter({
contentAreas: [variablesVBox, membersVBox, selectedMembersVBox]
});
splitter.setModel(model);
var okButton = new sap.m.Button({
text: "OK",
press: function(event) {
oDialog.close();
}
});
var cancelButton = new sap.m.Button({
text: "Cancel",
press: function(event) {
oDialog.close();
}
});
var oDialog = new sap.m.Dialog({
title: "Global Variables",
content: [splitter],
buttons: [okButton, cancelButton],
contentWidth: "70%",
contentHeight: "70%"
});
var oButton = new sap.m.Button({
text: "Open dialog",
press: function() {
oDialog.open();
}
}).placeAt("content");
</script>
</head>
<body class="sapUiBody">
<div id="content"></div>
</body>
</html>
sap.tnt.SideNavigation has to be placed inside sap.tnt.ToolPage in order to work properly. But the ToolPage control is meant to take the full width and height of the page, not only a part of it, like it would if placed inside Dialog. Therefore using this controls to achieve what you need is not possible.

Placing dynamic table in sapUI5 XML view

I'm trying to add dynamic table in sapui5 by using sap.ui.table.Table. But in this example using HTML view, but I want to XML for my view.
What is the alternative way to place the table in XML by using this way
<!DOCTYPE html>
<html><head>
<meta name="description" content="UI5 table example with local JSON model" />
<meta http-equiv='X-UA-Compatible' content='IE=edge' />
<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>
<title>SAPUI5 Dynamic Table</title>
<script id='sap-ui-bootstrap' type='text/javascript'
src='https://openui5.hana.ondemand.com/resources/sap-ui-core.js'
data-sap-ui-theme='sap_bluecrystal'
data-sap-ui-libs='sap.m,sap.ui.table'></script>
<script>
var columnData = [{
columnName: "firstName"
}, {
columnName: "lastName"
}, {
columnName: "department"
}];
var rowData = [{
firstName: "Sachin",
lastName: "Tendulkar",
department: "Cricket"
}, {
firstName: "Lionel",
lastName: "Messi",
department: "Football"
}, {
firstName: "Mohan",
lastName: "Lal",
department: "Film"
}];
var oTable = new sap.ui.table.Table({
visibleRowCount: 3
});
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData({
rows: rowData,
columns: columnData
});
oTable.setModel(oModel);
oTable.bindColumns("/columns", function(sId, oContext) {
var columnName = oContext.getObject().columnName;
return new sap.ui.table.Column({
label: columnName,
template: columnName,
});
});
oTable.bindRows("/rows");
page = new sap.m.Page({content:[
oTable
]});
app = new sap.m.App();
app.addPage(page);
app.placeAt("content");
</script>
</head>
<body class='sapUiBody'>
<div id='content'></div>
</body>
</html>
My XML file will look like
<mvc:View
controllerName="sap.ui.demo.toolpageapp.controller.Statistics"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc">
<Page showHeader="false">
<content>
<!-- want to place the table here -->
</content>
</Page>
You can achieve it using bindColumns() and bindRows()
XML view
<core:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" xmlns:ui="sap.ui.table"
controllerName="XXXX.Main" xmlns:html="http://www.w3.org/1999/xhtml">
<Page title="Dynamic Binding" class="sapUiContentPadding">
<content>
<ui:Table id="reOrderTable"></ui:Table>
</content>
</Page>
</core:View>
Controller.js
onInit: function() {
var oModel = this.getTableData(this);
this.createDynTable(this, oModel);
}
/**
* Get Data
*/
getTableData: function(that) {
var columnData = [
{ "colId": "Amt", "colName": "Amount", "colVisibility": true, "colPosition": 0 },
{ "colId": "Qty", "colName": "Quantity", "colVisibility": true, "colPosition": 1 },
{ "colId": "Unt", "colName": "Unit", "colVisibility": true, "colPosition": 2 },
{ "colId": "OPA", "colName": "OpenPOAmount", "colVisibility": true, "colPosition": 3 },
{ "colId": "OPQ", "colName": "OpenPOQuantity", "colVisibility": true, "colPosition": 4 }
];
var rowData = [{
"Amount": "200",
"Quantity": "RF",
"Unit": "CV",
"OpenPOAmount": "5988",
"OpenPOQuantity": "YY",
"EXT_FLDS": {
"PRINTING_NUM": {
"fieldvalue": 10,
"fieldlabel": "Printing Number",
"uictrl": "sap.m.Input"
},
"COUNTRY": {
"fieldvalue": "Thailand",
"fieldlabel": "Country",
"uictrl": "sap.m.ComboBox"
}
}
},
{
"Amount": "80",
"Quantity": "UG",
"Unit": "RT",
"OpenPOAmount": "878",
"OpenPOQuantity": "RF",
"EXT_FLDS": {
"PRINTING_NUM": {
"fieldvalue": 11,
"fieldlabel": "Printing Number",
"uictrl": "sap.m.Input"
},
"COUNTRY": {
"fieldvalue": "Thailand",
"fieldlabel": "Country",
"uictrl": "sap.m.ComboBox"
}
}
},
{
"Amount": "789",
"Quantity": "GV",
"Unit": "ED",
"OpenPOAmount": "8989",
"OpenPOQuantity": "FGG",
"EXT_FLDS": {
"PRINTING_NUM": {
"fieldvalue": 12,
"fieldlabel": "Printing Number",
"uictrl": "sap.m.Input"
},
"COUNTRY": {
"fieldvalue": "Thailand",
"fieldlabel": "Country",
"uictrl": "sap.m.ComboBox"
}
}
}
];
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData({
rows: rowData,
columns: columnData
});
return oModel;
},
/**
* Creating Dynamic table
*/
createDynTable: function(that, oModel) {
var oTable = this.byId("reOrderTable");
oTable.setModel(oModel);
oTable.bindColumns("/columns", function(sId, oContext) {
var columnName = oContext.getObject().colName;
return new sap.ui.table.Column({
label: columnName,
template: columnName,
});
});
oTable.bindRows("/rows");
}

Bind array to rows

I have an ajax json response and I have managed to bind the values into columns but I need to bind the values into rows.
I tried using oTable.bindRows("/"), but this binds the values into columns.
As a sample array I have : ( this is a response from a service )
Info [3]
[0] Object
name: "name",
surname: "surn"
[1] Object
address: "address",
phone: "22",
key: "val"
key2: "val2"
[2] Object
info: "information",
system: "sys",
data:"data here"
And I need a table( or a list ):
Key Value
name name
surname surn
phone 22
system sys
info information
You basically have to convert your Array. Please check below running example.
oData.forEach(function(data){
var keys = Object.keys(data);
keys.forEach(function(key){
oData_new.push({'key':key,'value':data[key]});
});
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<script src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js" id="sap-ui-bootstrap" data-sap-ui-theme="sap_belize" data-sap-ui-libs="sap.m"></script>
<script>
var oData = [{
name: "name",
surname: "surn"
}, {
address: "address",
phone: "22",
key: "val",
key2: "val2"
},
{
info: "information",
system: "sys",
data: "data here"
}
];
var oData_new = [];
oData.forEach(function(data) {
var keys = Object.keys(data);
keys.forEach(function(key) {
oData_new.push({
'key': key,
'value': data[key]
});
});
});
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData(oData_new);
var aColumns = [
new sap.m.Column({
header: new sap.m.Label({
text: "Key"
})
}),
new sap.m.Column({
header: new sap.m.Label({
text: "Value"
})
})
];
var oTable = new sap.m.Table({
columns: aColumns
});
oTable.setModel(oModel);
oTable.bindAggregation("items", {
path: "/",
template: new sap.m.ColumnListItem({
cells: [
new sap.m.Text({
text: {
path: 'key'
}
}),
new sap.m.Text({
text: {
path: 'value',
}
})
]
})
});
oTable.placeAt('content');
</script>
<body id="content" class="sapUiBody">
</body>
</html>

Get binding path of selectedItem in a sap.m.select element

A select element is a dropdown list in which an option may be selected.
The select element has the selectedItem which is a handle to the currently selected item. A selected item has a key that I bind to an identifying attribute in my JSON model.
Using an XML view declaration, I can use the change() event to fire code in the controller.
In the change() event how can I get the binding path of the selectedItem without having to search the model to match the key?
This is what I intuited but the second line throws an error.
onListSelect : function(event) {
console.log(event.oSource.getSelectedItem().getKey()) // works ok
var path = event.oSource.getSelectedItem().getBindingContext().getPath(); // Fails
}
EDIT: In response to input & comments I added the snippet to isolate the issue. In the course of doing so I find that there is no issue. The snippet works. Must have been my own mistake.
I shall erase the question shortly.
// JSON sample data
var data = {
"peeps": [
{className: "Coding 101", id: 100, firstName: "Alan", lastName: "Turing"},
{className: "Coding 101", id: 400, firstName: "Ada", lastName: "Lovelace"},
{className: "Combat 101", id: 300, firstName: "D", lastName: "Trump"},
{className: "Combat 101", id: 700, firstName: "Spartacus", lastName: ""},
{className: "Combat 101", id: 900, firstName: "Tasmanian", lastName: "Devil"}
]
};
sap.ui.getCore().attachInit(function() {
"use strict";
sap.ui.controller("MyController", {
onInit: function() {
// create JSON model instance
var oModel = new sap.ui.model.json.JSONModel();
// set the data for the model
oModel.setData(data);
// set model to core.
sap.ui.getCore().setModel(oModel);
},
onListSelect : function(event) {
console.log(event.getSource().getSelectedItem().getKey()); // works ok
var path = event.getSource().getSelectedItem().getBindingContext().getPath(); // Fails
console.log("Path=" + path)
var oModel = sap.ui.getCore().getModel()
var theName = oModel.getProperty(path)
console.log("You selected " + theName.lastName)
}
});
sap.ui.xmlview({
viewContent: jQuery("#myView").html()
}).placeAt("content");
});
<!DOCTYPE html>
<title>SAPUI5</title>
<script src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js" id="sap-ui-bootstrap" data-sap-ui-theme="sap_bluecrystal" data-sap-ui-libs="sap.m" data-sap-ui-bindingSyntax="complex" data-sap-ui-compatVersion="edge" data-sap-ui-preload="async"></script>
<script id="myView" type="ui5/xmlview">
<mvc:View controllerName="MyController" xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns:layout="sap.ui.commons.layout" xmlns:f="sap.ui.layout.form">
<Select id="theList" forceSelection="false" wisth="auto" change="onListSelect" items="{
path: '/peeps',
sorter: { path: 'lastName' }
}" class="sapUiResponsiveMargin">
<core:Item key="{id}" text="{lastName}" />
</Select>
</mvc:View>
</script>
<body class="sapUiBody">
<div id="content"></div>
</body>
Check following XML and JS code :
XML Code :
`<Select id="id_Select"
forceSelection="false"
selectedKey="{/Data/0/key}"
change="fnSelectChange"
items="{/Data}" >
<core:Item key="{key}" text="{name}" />
</Select>`
JS Code :
fnInputHandel : function(){
oSelectJSON = new sap.ui.model.json.JSONModel();
var Data = {
Data : [{
name : "name1",
key : "key1"
},{
name : "name2",
key : "key2"
}]
}
oSelectJSON.setData(Data);
this.getView().byId("id_Select").setModel(oSelectJSON);
},
fnSelectChange : function(oEvent){
var value = oEvent.oSource.getSelectedItem().getBindingContext().getPath();
},

binding is not working in javascript model

I created javascript view
sap.ui.jsview("view.taskListView", {
/** Specifies the Controller belonging to this View.
* In the case that it is not implemented, or that "null" is returned, this View does not have a Controller.
* #memberOf view.taskListView
*/
getControllerName : function() {
return "view.taskListView";
},
/** Is initially called once after the Controller has been instantiated. It is the place where the UI is constructed.
* Since the Controller is given to this method, its event handlers can be attached right away.
* #memberOf view.taskListView
*/
createContent : function(oController) {
var oLabel = new sap.m.Label("l1",{ text :"Weekly Tasks", textAlign:"Center", width:"100%"});
// var oList = new sap.m.List({noDataText:"No data", items:"{/modelData}"});
var oList= new sap.m.List({ // define List Control
// mode: "MultiSelect", // multi selection mode
columns : [
new sap.m.Column({ // first column
}),
new sap.m.Column({ // second column
})
],
items : [
new sap.m.ColumnListItem({ // first row
type : "Navigation",
//selected : true, // first item is selected (from ListItemBase)
cells : [
new sap.ui.core.Icon({
src : "{/iconTaskSource}",
size : "1.5em"
}),
new sap.m.Text({ // second cell related to second column definition
text : "{/taskName}"
})
]
}),
new sap.m.ColumnListItem({ // second row
type : "Navigation",
cells : [
new sap.ui.core.Icon({
src : "{/iconTaskSource}",
size : "1.5em"
}),
new sap.m.Text({ // second cell related to second column definition
text : "{/taskName}"
})
]
})
]
});
return new sap.m.Page({
title: "Title",
content: [
oLabel , oList
/*
new sap.m.Button({
text:"Go to Page2",
tap: function(){
//app.to("abc.SecondPage");
alert("Hello");
}
})
*/
]
});
}
});
and controller
sap.ui.controller("view.weeklyTasks", {
onInit: function() {
var aData2 = { modelData : [
{iconTaskSource:"icon1", taskName: "task1"},
{iconTaskSource:"icon2", taskName: "task2"}
]};
var oModel = new sap.ui.model.json.JSONModel(aData2);
this.getView().setModel(oModel2);
}
});
The binding is not working
Did I miss something ?
Try running this code snippet.
sap.ui.jsview("view.taskListView", {
getControllerName: function() {
return "view.taskListView";
},
createContent: function(oController) {
var oLabel = new sap.m.Label("l1", {
text: "Weekly Tasks",
textAlign: "Center",
width: "100%"
});
var oList = new sap.m.List({ // define List Control
columns: [
new sap.m.Column({ // first column
})
]
});
var oTemplate = new sap.m.ColumnListItem({
type: "Navigation",
cells: [
new sap.m.Text({
text: "{taskName}"
})
]
});
oList.bindItems('/modelData', oTemplate);
return new sap.m.Page({
title: "Title",
content: [
oLabel, oList
]
});
}
});
sap.ui.controller("view.taskListView", {
onInit: function() {
var aData2 = {
modelData: [
{
iconTaskSource: "icon1",
taskName: "task1"
}, {
iconTaskSource: "icon2",
taskName: "task2"
}
]
};
var oModel = new sap.ui.model.json.JSONModel(aData2);
this.getView().setModel(oModel);
}
});
var oApp = new sap.m.App();
var myView = sap.ui.view({
type: sap.ui.core.mvc.ViewType.JS,
viewName: "view.taskListView"
});
oApp.addPage(myView);
oApp.placeAt('content');
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='X-UA-Compatible' content='IE=edge' />
<title>test</title>
<script id='sap-ui-bootstrap' type='text/javascript' src='https://openui5.hana.ondemand.com/resources/sap-ui-core.js' data-sap-ui-theme='sap_bluecrystal' data-sap-ui-libs='sap.m'></script>
</head>
<body class='sapUiBody'>
<div id='content'></div>
</body>
</html>
Check this for the fixed version of your code http://jsbin.com/kequme/1/edit
You neeed to include data-sap-ui-xx-bindingSyntax="complex" in index.html file.
Look:
<script src="resources/sap-ui-core.js" id="sap-ui-bootstrap"
data-sap-ui-xx-bindingSyntax="complex" data-sap-ui-libs="sap.m"
data-sap-ui-theme="sap_bluecrystal">
</script>