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

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();
},

Related

sap.ui.table.table with text wrapping (render issue)

i've got a sap.ui.table with visibleRowCountMode="Auto" binded with a JSON Model.
In my ColumnBinding I use a sap.m.text element as a template to wrap the text if its too long for the columnWidth.
It seems like the table doesnt refresh the actual height and the row count if the rows are rebinded to the table.
If the rows exceed the actual screensize no scrollbar is added to the table.
I created a bin to show the example coding of my table:
https://jsbin.com/noxaqofeci/edit?html,js,output
--> if you resize the column and the table doesnt fit into the screen the issue will appear.
Am i missing something or is there any way to fix this?
Thanks!
example code for my problem:
<!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: "3lines3lines3lines3lines3lines3lines",
lastName: "empty",
department: "empty"
}, {
firstName: "3lines3lines3lines3lines3lines3lines",
lastName: "empty",
department: "empty"
},{
firstName: "3lines3lines3lines3lines3lines3lines",
lastName: "empty",
department: "empty"
},{
firstName: "3lines3lines3lines3lines3lines3lines",
lastName: "empty",
department: "empty"
},{
firstName: "3lines3lines3lines3lines3lines3lines",
lastName: "empty",
department: "empty"
},{
firstName: "3lines3lines3lines3lines3lines3lines",
lastName: "empty",
department: "empty"
},{
firstName: "3lines3lines3lines3lines3lines3lines",
lastName: "empty",
department: "empty"
},{
firstName: "3lines3lines3lines3lines3lines3lines",
lastName: "empty",
department: "empty"
},{
firstName: "3lines3lines3lines3lines3lines3lines",
lastName: "empty",
department: "empty"
}];
var oTable = new sap.ui.table.Table({
visibleRowCountMode: "Auto"
});
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({
width: "120px",
label: columnName,
template: new sap.m.Text({text: {path:columnName}})
});
});
oTable.bindRows("/rows");
page = new sap.m.Page({content:[
oTable,new sap.m.Link({text:"Click For More Info",target:"_blank"})
]});
app = new sap.m.App();
app.addPage(page);
app.placeAt("content");
</script>
</head>
<body class='sapUiBody'>
<div id='content'></div>
</body>
</html>
Question can be closed. Sap.ui.table.table is not meant to change its row height dynamically.
https://experience.sap.com/fiori-design-web/grid-table/
--> section cell level, search key: wrap

How to dynamically bind items of sap.m.Select

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>

TypeError: oRouter.getRoute(...) is undefined

I am new to SAPUI5 and I would like to navigate to the details of an object on a second view, but I have an error:
TypeError: oRouter.getRoute (...) is undefined
Can someone help me?
Airport.controller.js
onInit: function() {
jQuery.sap.require("sap.m.ObjectAttribute");
jQuery.sap.require("sap.m.MessageBox");
var oList = this.getView().byId("List01");
oList.bindItems({
path: "JSON>/products",
template: new sap.m.StandardListItem({
type: "Navigation",
title: "{JSON>fields/aeroport}",
press: [this.onPress, this],
}),
});
},
onPress: function(oEvt) {
var oItem = oEvt.getSource();
var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
var temp = oItem
.getBindingContext("JSON")
.getPath()
.substr(10);
oRouter.navTo("Detail", {
airportPath: temp,
});
},
Detail.controller.js
onInit: function() {
var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
oRouter.getRoute("detail").attachPatternMatched(this._onObjectMatched, this);
},
_onObjectMatched: function(oEvt) {
this.getView().bindElement({
path: "/products/" + oEvt.getParameter("arguments").airportPath,
model: "JSON",
});
},
Detail.view.xml
<mvc:View
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m"
controllerName="SAPUI5CoolProject.controller.Detail"
>
<App id="Detail">
<Page
title="Airport Detail"
showNavButton="true"
navButtonPress="goBackOtherAirport"
>
<ObjectHeader title="{JSON>products/fields}"/>
</Page>
</App>
</mvc:View>
manifest.json
{
"pattern": "Detail/{airportPath}",
"name": "Detail",
"target": ["Detail"]
}
oRouter.getRoute("detail") → oRouter.getRoute("Detail")
Since the API getRoute awaits the name of the route defined in the app descriptor, and because JS is case-sensitive, the exact same string literal has to be passed as the argument.

SapUI5 - How can i bind an object Master-Detail page?

I'm trying to bind and present an element to a detail page, but no success about it.
the master page is displayed well and present the data.
but when i want to present the item on a detail page the data doesn't displayed.
*for fetching all the data i use an API request
I'm not sure what am i doing wrong.
Heres the code:
Controller.Overview.js
var data = {id: 19265, typeId: 5, foreignKeyId: 1, foreignKeyTextId: "316e2c71-d1d1-f73c-4696-70912d6cf240", value: 0, Name: "jim"}
,{id: 19268, typeId: 5, foreignKeyId: 1, foreignKeyTextId: "316e2c71-d1d1-f73c-4696-70912d6cf240", value: 0, Name: "john"}
var newArr2 = {"Overview" : data};
oModel.setData(newArr2);
oView.setModel(oModel);
onListItemPressed : function(oEvent){
var oItem, oCtx;
oItem = oEvent.getSource();
oCtx = oItem.getBindingContext();
this.getRouter().navTo("overviewItem",{
OverviewId : oCtx.getProperty("OverviewId")
});
}
Overview.xml
<List id="dataJS" headerText="dataJS" items="{/Overview}">
<items>
<StandardListItem
title="{foreignKeyTextId}"
iconDensityAware="false"
iconInset="false"
type="Navigation"
press="onListItemPressed"/>
</items>
</List>
controller.Overviewitem.js
return BaseController.extend("com.sap.it.cs.itsupportportaladmin.controller.feedbackanalytics.OverviewItem", {
_formFragments: {},
onInit: function () {
var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
oRouter.getRoute("overviewItem").attachMatched(this._onRouteMatched, this);
},
_onRouteMatched : function (oEvent) {
var oArgs, oView;
oArgs = oEvent.getParameter("arguments");
oView = this.getView();
oView.bindElement({
path : "/Overview(" + oArgs.OverviewId + ")",
events : {
change: this._onBindingChange.bind(this),
dataRequested: function (oEvent) {
oView.setBusy(true);
},
dataReceived: function (oEvent) {
oView.setBusy(false);
}
}
});
},
_onBindingChange : function (oEvent) {
// No data for the binding
if (!this.getView().getBindingContext()) {
this.getRouter().getTargets().display("notFound");
}
}
});
OverviewItem.xml
<mvc:View
controllerName="com.sap.it.cs.itsupportportaladmin.controller.feedbackanalytics.OverviewItem"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc"
xmlns:f="sap.ui.layout.form"
busyIndicatorDelay="0">
<Page
id="overviewPage"
title="{Name}"
showNavButton="true"
navButtonPress="onNavBack"
class="sapUiResponsiveContentPadding">
<content>
<Panel
id="employeePanel"
width="auto"
class="sapUiResponsiveMargin sapUiNoContentPadding">
<headerToolbar>
<Toolbar>
<Title text="{OverviewId}" level="H2"/>
<ToolbarSpacer />
<Link text="{i18n>FlipToResume}" tooltip="{i18n>FlipToResume.tooltip}" press="onShowResume" />
</Toolbar>
</headerToolbar>
</Panel>
</content>
</Page>
</mvc:View>
I see two issues:
/Overview(" + oArgs.OverviewId + ")" will not work as your model an array and not object as per code in Controller.Overview.js:
var data = {id: 19265, typeId: 5, foreignKeyId: 1, foreignKeyTextId: "316e2c71-d1d1-f73c-4696-70912d6cf240", value: 0, Name: "jim"}
,{id: 19268, typeId: 5, foreignKeyId: 1, foreignKeyTextId: "316e2c71-d1d1-f73c-4696-70912d6cf240", value: 0, Name: "john"}
var newArr2 = {"Overview" : data};
oModel.setData(newArr2);
// this resolves to :
newArr2 = {"Overview" : [ {id: 19265...}, {id: 19268...} ]}
oView.setModel(oModel);
You will have to find index of Clicked item and do :
/Overview/" + oArgs.OverviewIndex resulting in somethin like: Overview/0 or Overview/1 etc.
Also, you have set the model only to your master list.
oView.setModel(oModel); where oView is in Controller.Overview.js.
Please set the model to your complete split-app for binding context to work correctly.
===========
Update after Discussion: Store you data as an Object:
// id as the key. SO, you can easily fetch person.
var data = {
"19265" : {id: 19265, typeId: 5, foreignKeyId: 1, foreignKeyTextId: "316e2c71-d1d1-f73c-4696-70912d6cf240", value: 0, Name: "jim"},
"19268" : {id: 19268, typeId: 5, foreignKeyId: 1, foreignKeyTextId: "316e2c71-d1d1-f73c-4696-70912d6cf240", value: 0, Name: "john"}
};
And Set binding on click as:
oView.bindElement({
path : "/Overview/" + oArgs.OverviewId + "",
events : {
change: this._onBindingChange.bind(this),
dataRequested: function (oEvent) {
oView.setBusy(true);
}, ... rest of code.

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>