Sort table by certain parts of string only - sapui5

The sorting works basically fine using the sorter. One column is the full name (e.g. "Steve Jobs"). I have only the full name in that entity set but I want to sort the entries by the last name (last word of the full name) when clicking the full name column header. Is there some way to do this?

You'll need to define a custom comparator for the sorter which applies only if all the entities are available client-side, for example, by having the operationMode set to 'Client' when defining the OData list binding.API
sap.ui.getCore().attachInit(() => sap.ui.require([
"sap/ui/model/odata/v2/ODataModel",
"sap/ui/core/mvc/XMLView",
"sap/ui/model/json/JSONModel",
"sap/ui/model/Sorter",
], (ODataModel, XMLView, JSONModel, Sorter) => {
"use strict";
const odataModel = new ODataModel({
serviceUrl: [
"https://cors-anywhere.herokuapp.com/",
"https://services.odata.org/V2/Northwind/Northwind.svc/",
].join(""),
tokenHandling: false,
preliminaryContext: true,
});
Promise.all([
odataModel.metadataLoaded(),
sap.ui.getCore().loadLibrary("sap.m", true),
]).then(() => XMLView.create({
definition: `<mvc:View xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m"
xmlns:core="sap.ui.core"
height="100%"
>
<App>
<Page showHeader="false">
<Table id="myResponsiveTable"
items="{
path: '/Customers',
parameters: {
select: 'CustomerID, ContactName',
operationMode: 'Client'
}
}"
>
<columns>
<Column id="customerIdColumn"
sortIndicator="{colCustomerId>/sortOrder}"
width="33%"
>
<Text text="Customer ID">
<customData>
<core:CustomData
key="sorterPath"
value="CustomerID"
/>
</customData>
</Text>
</Column>
<Column id="fullNameColumn"
sortIndicator="{colFullName>/sortOrder}"
width="auto"
>
<Text text="Full Name">
<customData>
<core:CustomData
key="sorterPath"
value="ContactName"
/>
</customData>
</Text>
</Column>
</columns>
<ColumnListItem>
<Text text="{CustomerID}" />
<Text text="{ContactName}" />
</ColumnListItem>
</Table>
</Page>
</App>
</mvc:View>`,
afterInit: function() { // === onInit
const table = this.byId("myResponsiveTable");
activateColumnPress(table, onColumnPress);
},
models: {
undefined: odataModel,
colCustomerId: new JSONModel({ sortOrder: "None" }),
colFullName: new JSONModel({ sortOrder: "None" }),
}
}).then(view => view.placeAt("content")));
function activateColumnPress(table, handler) {
// Making columns clickable for the demo
table.bActiveHeaders = true;
table.onColumnPress = col => handler(table, col);
}
function onColumnPress(table, pressedCol) {
table.getColumns()
.filter(col => !(col.getSortIndicator() === pressedCol.getSortIndicator()))
.map(col => col.setSortIndicator("None"));
table.getBinding("items").sort(createSorter(pressedCol));
}
function createSorter(column) {
return column.getHeader().data("sorterPath") === "ContactName"
? createFullNameSorter(column, toggleSort(column.getModel("colFullName")))
: createCustomerIdSorter(column, toggleSort(column.getModel("colCustomerId")));
}
function toggleSort(colModel) {
const descending = colModel.getProperty("/sortOrder") !== "Ascending";
colModel.setProperty("/sortOrder", descending ? "Ascending" : "Descending");
return !descending;
}
function createFullNameSorter(column, descending) {
const comparator = (a, b) => a.split(" ").pop().localeCompare(b.split(" ").pop());
return new Sorter("ContactName", descending, false, comparator);
}
function createCustomerIdSorter(column, descending) {
return new Sorter("CustomerID", descending);
}
}));
<script id="sap-ui-bootstrap"
src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-libs="sap.ui.core"
data-sap-ui-async="true"
data-sap-ui-compatversion="edge"
data-sap-ui-theme="sap_belize"
data-sap-ui-xx-waitfortheme="true"
></script>
<body id="content" class="sapUiBody sapUiSizeCompact" style="height: 100%;"></body>
Btw: the "Client" operation mode currently doesn't fetch all entities if the service has server-side paging implemented.
As you can see in the example above, the Sorter constructor can handle custom comparator which will be invoked when the sort method is called. For comparing last parts of the full names, you can define the comparator like this:
function compare(fullName_a, fullName_b) {
const lastPart_a = fullName_a.split(" ").pop();
const lastPart_b = fullName_b.split(" ").pop();
return lastPart_a.localeCompare(lastPart_b); // 0 if equal. Otherwise a negative or positive number
}

Related

Table grouping resets selected values when adding new item

Here we have a very basic table with an Add button and grouping activated. When I select values for the existing items and then press the button to add a new row, my selected values are getting reset, but without grouping it works fine. Am I doing something wrong or is this a bug?
sap.ui.getCore().attachInit(() => sap.ui.require([
"sap/ui/core/mvc/XMLView",
"sap/ui/model/json/JSONModel" // sample model. Can be also an ODataModel.
], async (XMLView, JSONModel) => {
"use strict";
const control = await XMLView.create({
definition: `<mvc:View xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc">
<Table items="{
path: '/tableItems',
sorter: { path : 'group', group: true }
}">
<headerToolbar>
<OverflowToolbar>
<Title text="Test Table" />
<ToolbarSpacer/>
<Button id="addButton" text="Add" type="Emphasized" />
</OverflowToolbar>
</headerToolbar>
<columns>
<Column width="20rem">
<Label text="col0"/>
</Column>
<Column width="20rem">
<Label text="col1"/>
</Column>
</columns>
<ColumnListItem vAlign="Middle">
<Text text="{text}" />
<Select forceSelection="false" width="100%" xmlns:core="sap.ui.core">
<core:Item text="test1" key="test1" />
<core:Item text="test2" key="test2" />
<core:Item text="test3" key="test3" />
<core:Item text="test4" key="test4" />
</Select>
</ColumnListItem>
</Table>
</mvc:View>`,
afterInit: function() {
this.byId("addButton").attachPress(onPressAdd, this);
function onPressAdd() {
const oModel = this.getModel();
const aItems = oModel.getProperty("/tableItems");
const newItems = aItems.concat({
group: "3",
text: "3-1",
key: "3-1",
});
oModel.setProperty("/tableItems", newItems);
}
},
models: new JSONModel({
number: 0,
tableItems: [
{
group: "1",
text: "1-1",
key: "1-1",
},
{
group: "1",
text: "1-2",
key: "1-2",
},
{
group: "2",
text: "2-1",
key: "2-1",
},
{
group: "2",
text: "2-2",
key: "2-2",
},
],
}),
});
control.placeAt("content");
}));
<script id="sap-ui-bootstrap"
src="https://openui5.hana.ondemand.com/1.82.2/resources/sap-ui-core.js"
data-sap-ui-libs="sap.ui.core,sap.m"
data-sap-ui-theme="sap_fiori_3"
data-sap-ui-compatversion="edge"
data-sap-ui-async="true"
data-sap-ui-excludejquerycompat="true"
data-sap-ui-xx-waitfortheme="init"
></script>
<body id="content" class="sapUiBody sapUiSizeCompact"></body>
Set the growing="true" to the sap.m.Table.
This enables GrowingEnablement internally which prevents rerendering the entire ListBase (Table) when the target gets invalidated. Only the necessary item will be then appended to the table.
Generally, in order to optimize the rendering behavior, it's always a good practice to..:
Enable the growing property if the table / list is editable, shrinkable, or expandable.
Add key: <propertyName with unique values> to the ListBinding info object to benefit from the Extended Change Detection if the model is a client-side model such as JSONModel. With an ODataModel, the key is automatically added by the framework.
<Table xmlns="sap.m"
growing="true"
items="{
path: 'myModel>/myCollection',
key: <propertyName>, (if 'myModel' is not an ODataModel)
sorter: ...
}"
>

Manipulating icons in the table row based on condition

I have the sap.ui.table.Table in XML view as below:
<Table id="testtable" xmlns="sap.ui.table"
rows="{/testdata}"
alternateRowColors="true">
<columns>
<Column hAlign="Center" label="Col1">
<template>
<m:Text text="{dataX}" wrapping="false" />
</template>
</Column>
<Column hAlign="Center" label="Col2">
<template>
<m:Text text="{dataY}" wrapping="false" />
</template>
</Column>
<Column label="Col3">
<template>
<m:HBox>
<core:Icon src="sap-icon://show" color="#007bff" />
<core:Icon src="sap-icon://edit" color="#007bff" />
<core:Icon src="sap-icon://print" color="#007bff" />
</m:HBox>
</template>
</Column>
</columns>
</Table>
Here what I am trying to achieve is for different rows I want to change the properties of Icons as:
To achieve this, I did something as:
Code below is what I tried for manipulating (not to get exactly as in image)
var noOfrows = data.length; // data is here table rows data
var tabItems = this.byId("testtable").getRows();
if (noOfrows != 1) {
for (var i = 0; i < noOfrows - 1; i++) {
var cells = tabItems[i].getCells();
cells[2].mAggregations.items[0].setColor("#000000");
cells[2].mAggregations.items[1].setColor("#c2baba");
cells[2].mAggregations.items[2].setColor("#000000");
}
} else {
var cells = tabItems[0].getCells();
cells[2].mAggregations.items[0].setColor("#007bff");
cells[2].mAggregations.items[1].setColor("#007bff");
cells[2].mAggregations.items[2].setColor("#007bff");
}
This does the thing but I have read this to be very bad. I have no idea how I could do this in a proper way.
I am trying to accomplish this by keeping table, columns in XML view (if this is possible) as above instead of adding dynamically from controller.
The sample of data looks as:
var testdata = [{test: "A", data:'eg1'},
{test: "B", data:'eg2'},
{test: "C", data:'eg3'}]
Here is a worked example - it will move you towards where you need to go (as I would not put the formatting function in the controller but in a separate js file). Can do that later if you need me to.
Set you Icons colours to depend on the variable 'test' you allude to in your comment by calling the setIconColour function that returns a valid Icon colour.
<core:Icon src="sap-icon://show" color="{path: 'test', formatter: '.setIconColour'}" />
Set a value for test in your data:
{"testdata": [
{ "dataX": 1, "dataY": "testdata", "test": 0},
{ "dataX": 2, "dataY": "testdata", "test": 2},
{ "dataX": 3, "dataY": "testdata", "test": 3},
{ "dataX": 4, "dataY": "testdata", "test": 1}
]}
Use the value of test to set the icon colour in a function (below is an example):
setIconColour: function (value) {
if (value === 0) {
return "Default";
} else if (value === 1) {
return "#007bff";
} else if (value === 2) {
return "Positive";
} else if (value === 3) {
return "Negative";
}
}
The icon colour will now be a function of the value of the variable 'test'.
Addition - code snippet included (THIS IS NOT HOW YOU BUILD A SAPUI5 APP - this is to illustrate this with a WORKING example from which to learn or with which you can play)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>example conditional formatter</title>
<script
src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-theme="sap_belize_plus"
data-sap-ui-libs="sap.m"
data-sap-ui-bindingSyntax="complex"
data-sap-ui-compatVersion="edge"
data-sap-ui-preload="async"></script>
<!-- use "sync" or change the code below if you have issues -->
<!-- XMLView -->
<script id="myXmlView" type="ui5/xmlview">
<mvc:View
controllerName="MyController"
xmlns:m="sap.m"
xmlns="sap.ui"
xmlns:core="sap.ui.core"
xmlns:mvc="sap.ui.core.mvc">
<Table id="testtable" xmlns="sap.ui.table"
rows="{/testdata}"
alternateRowColors="true">
<columns>
<Column hAlign="Center" label="Col1">
<template>
<m:Text text="{dataX}" wrapping="false" />
</template>
</Column>
<Column hAlign="Center" label="Col2">
<template>
<m:Text text="{dataY}" wrapping="false" />
</template>
</Column>
<Column label="Col3">
<template>
<m:HBox>
<core:Icon src="sap-icon://show" color="{path: 'test', formatter: '.setIconColour'}" />
<core:Icon src="sap-icon://edit" color="{path: 'test', formatter: '.setIconColour'}" />
<core:Icon src="sap-icon://print" color="{path: 'test', formatter: '.setIconColour'}" />
</m:HBox>
</template>
</Column>
</columns>
</Table>
</mvc:View>
</script>
<script>
sap.ui.getCore().attachInit(function () {
"use strict";
//### Controller ###
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/json/JSONModel"
], function (Controller, JSONModel, XMLModel) {
"use strict";
return Controller.extend("MyController", {
onInit : function () {
var that = this;
let model = new JSONModel(this.getData());
this.getView().setModel(model);
},
setIconColour: function (value) {
if (value === 0) {
return "Default";
} else if (value === 1) {
return "#007bff";
} else if (value === 2) {
return "Positive";
} else if (value === 3) {
return "Negative";
}
},
getData: function(){
return {"testdata": [
{ "dataX": 1, "dataY": "testdata", "test": 0},
{ "dataX": 2, "dataY": "testdata", "test": 2},
{ "dataX": 3, "dataY": "testdata", "test": 3},
{ "dataX": 4, "dataY": "testdata", "test": 1}
]};
}
})
});
//### THE APP: place the XMLView somewhere into DOM ###
sap.ui.xmlview({
viewContent : jQuery("#myXmlView").html()
}).placeAt("content");
});
</script>
</head>
<body class="sapUiBody">
<div id="content"></div>
</body>
</html>
Add Tag Like below:
<core:Icon id="tblColIcon"
src="{path:'Salary', formatter:'.formatter.setIconFF'}"
tooltip="{path:'Salary', formatter:'.formatter.setIconToolTipFF'}"
color="{path:'Salary', formatter:'.formatter.setIconColorFF'} >
In formatter.js you can define your condition and return the value.

Add a New Item to a Table / List

I have a fragment / view written in XML which contains a simple table with some columns and one ColumnListItem:
<m:Table id="CorrectiveActionsTable">
<m:columns>
<m:Column>
<m:Text text="Lfd. Nr"/>
</m:Column>
<m:Column width="30%">
<m:Text text=""/>
</m:Column>
<m:Column>
<m:Text text="gefordert von"/>
</m:Column>
<m:Column>
<m:Text text="Durchführungsverantwortung"/>
</m:Column>
<m:Column>
<m:Text text="Planungstermin"/>
</m:Column>
<m:Column>
<m:Text text="IST-Termin"/>
</m:Column>
</m:columns>
<m:ColumnListItem id="ListItem_00">
<m:Text text="1"/>
<m:TextArea
value="senf"
rows="6"
width="100%"
/>
<m:Input placeholder="bla"/>
<m:Input placeholder="bla2"/>
<m:DatePicker placeholder="bla3"/>
<m:DatePicker placeholder="bla4"/>
</m:ColumnListItem>
</m:Table>
<m:HBox>
<m:Button
text="Add Button"
visible="true"
press="onAddButton"
icon="sap-icon://add"
/>
</m:HBox>
The Button should be used to add a new ColumnListItem to the Table.
I think I should write the onAddButton function in the controller but I don't know where to start.
For now, my controller looks like this:
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/m/ColumnListItem",
"sap/m/Text",
"sap/m/TextArea",
"sap/m/Input",
"sap/m/DatePicker"
], function(Controller, ColumnListItem, Text, TextArea, Input, DatePicker) {
"use strict";
return Controller.extend("...", {
onAddButton: function(oEvent) {
var columnListItemNewLine = new ColumnListItem({
cells: [
new Text({
text: "1"
}),
new TextArea({
value: "senf",
rows: "6",
width: "30%"
}),
new Input({
type: "text",
placeholder: "bla"
}),
new Input({
type: "text",
placeholder: "bla2"
}),
new DatePicker({
placeholder: "bla3"
}),
new Datepicker({
placeholder: "bla4"
})
]
});
this._oTable.addItem(columnListItemNewLine);
}
});
});
And I'm pretty sure there is a better way to do this than my approach.
Resolution
Bind the collection of data to the aggregation of table (e.g. <items>).
Add a new entry via the model (instead of to the UI directly) when the user clicks on Add.
Thanks to the aggregation binding, UI5 will create a new sap.m.ColumnListItem for you and you did not break the MVC pattern. Here are some examples, using..:
v2.ODataModel
Call createEntry and later submitChanges to send it to backend.
Demo: plnkr.co/F3t6gI8TPUZwCOnA (Click on the Add button to create a new "Flight").
Documentation: OData V2 - Creating Entities
v4.ODataModel
See the documentation topic OData V4 - Creating an Entity.
JSONModel
globalThis.onUI5Init = () => sap.ui.require([
"sap/ui/core/mvc/XMLView",
"sap/ui/model/json/JSONModel",
], async (XMLView, JSONModel) => {
"use strict";
const control = await XMLView.create({
definition: document.getElementById("myxmlview").textContent,
models: new JSONModel({
myArray: [],
}),
});
control.placeAt("content");
});
function onAddItemPress(event) {
const model = event.getSource().getModel();
const newArray = model.getProperty("/myArray").concat({
id: globalThis.crypto.randomUUID(),
text: "My New Item",
});
model.setProperty("/myArray", newArray, null, true);
}
html, body { height: 100%; }
body { margin: 0; }
<script defer id="sap-ui-bootstrap"
src="https://sdk.openui5.org/resources/sap-ui-core.js"
data-sap-ui-oninit="onUI5Init"
data-sap-ui-libs="sap.ui.core,sap.m"
data-sap-ui-theme="sap_horizon"
data-sap-ui-async="true"
data-sap-ui-compatversion="edge"
data-sap-ui-excludejquerycompat="true"
data-sap-ui-xx-waitfortheme="init"
></script>
<script id="myxmlview" type="text/xml">
<mvc:View xmlns:mvc="sap.ui.core.mvc" height="100%" displayBlock="true">
<Page xmlns="sap.m" title="My Items ({= ${/myArray}.length})">
<headerContent>
<Button text="Add" type="Emphasized" press="onAddItemPress" />
</headerContent>
<Table xmlns="sap.m"
growing="true"
items="{
path: '/myArray',
templateShareable: false,
key: 'id'
}">
<columns>
<Column>
<Text text="UUID" />
</Column>
<Column>
<Text text="Text" />
</Column>
</columns>
<ColumnListItem>
<Text text="{id}" />
<Text text="{text}" />
</ColumnListItem>
</Table>
</Page>
</mvc:View>
</script>
<body id="content" class="sapUiBody sapUiSizeCompact">
</body>
For client-side models such as JSONModel, calling setProperty is sufficient. DO NOT use push or modify the internal model reference directly.
⚠️ Note
Do not modify the control aggregation manually, e.g. via myListControl.addItem, after binding the aggregation (items). Instead, apply the changes from the model as described above.
Try with this code below
onAddButton: function(oEvent){
var columnListItemNewLine = new sap.m.ColumnListItem({
cells:[
new sap.m.Text({text: "1"}),
new sap.m.TextArea({value: "senf", rows: "6", width:
"30%"}),
new sap.m.Input({type: "text", placeholder: "bla"}),
new sap.m.Input({type: "text", placeholder: "bla2"}),
new sap.m.DatePicker({placeholder: "bla3"}),
new sap.m.Datepicker({placeholder: "bla4"})
]
});
this._oTable.removeAllItems();
this._oTable.addItem(columnListItemNewLine);
}

Access model defined in manifest

Using single model definition in manifest.json
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "....i18n.i18n"
}
},
"": {
"dataSource": "mainService"
}
}
i can bind to model from XML and it's work
<List items="{path: '/myOneSet'}"> ... </List>
<List items="{path: '/myTwoSet'}"> ... </List>
but i can not access to it from code
this.getView().getModel().getProperty('/myOneSet')
or
this.getView().getModel().getProperty('/myOneSet/>param')
not work. How it accessible?
If mainService is an OData service, then your model is an ODataModel. You can access data via methods described in the API, e.g.: read()
this.getView().getModel().read('/myOneSet', {
success: function(oData, response) {
// do sg. with oData
}
});
Most of its data access methods has a second parameter-object with a success function callback. This function will be called asynchronously with the data on the given path upon successful data retrieval from the datasource. Most of the ODataModel API methods works with callbacks. You can read more about callbacks here.
If you defined model in the manifest.json file then you can access it via Component. If you created your project via template then you have a BaseController.js file which is the ancestor of your other controllers and there is a function getComponentModel. So, I would suggest you to try this code in your controller:
this.getComponentModel().getProperty('/myOneSet')
Because of the property name that you try to access I assume you are using an ODataModel. Is that correct?
If that's true you have to consider a few things... ODataModel.getProperty() does not trigger requests. Instead it will return whats already available. If you want to trigger a request you should execute an ODataModel.read(). If you want to get the loaded data from the ODataModel then you should also know when the data has been loaded. This you can achieve by attaching a change event handler when you do the binding.
Instead of describing how to access the data of an ODataModel I wrote s little jsbin example for you (or see below). Just check the change event handler. There are multiple ways to access the data.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SAPUI5 single file template | nabisoft</title>
<script src="https://openui5.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>
<!-- use "sync" or change the code below if you have issues -->
<!-- XMLView -->
<script id="myXmlView" type="ui5/xmlview">
<mvc:View
controllerName="MyController"
xmlns="sap.m"
xmlns:core="sap.ui.core"
xmlns:mvc="sap.ui.core.mvc">
<Table
id="myTable"
growing="true"
growingThreshold="10"
growingScrollToLoad="true"
busyIndicatorDelay="0">
<headerToolbar>
<Toolbar>
<Title text="Orders of ALFKI"/>
<ToolbarSpacer/>
</Toolbar>
</headerToolbar>
<columns>
<Column>
<Text text="OrderID"/>
</Column>
<Column>
<Text text="Order Date"/>
</Column>
<Column>
<Text text="To Name"/>
</Column>
<Column>
<Text text="Ship City"/>
</Column>
</columns>
<items>
<!-- filled via bindItems() in controller -->
</items>
</Table>
</mvc:View>
</script>
<!-- XML Fragment -->
<script id="myXMLFragment" type="ui5/fragment">
<core:FragmentDefinition
xmlns="sap.m"
xmlns:core="sap.ui.core">
<ColumnListItem type="Active">
<cells>
<ObjectIdentifier title="{OrderID}"/>
<Text
text="{
path:'OrderDate',
type:'sap.ui.model.type.Date',
formatOptions: { style: 'medium', strictParsing: true}
}"/>
<Text text="{ShipName}"/>
<Text text="{ShipCity}"/>
</cells>
</ColumnListItem>
</core:FragmentDefinition>
</script>
<script>
sap.ui.getCore().attachInit(function () {
"use strict";
//### Controller ###
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/odata/v2/ODataModel"
], function (Controller, ODataModel) {
"use strict";
return Controller.extend("MyController", {
onInit : function () {
this.getView().setModel(
new ODataModel("https://cors-anywhere.herokuapp.com/services.odata.org/V2/Northwind/Northwind.svc/", {
json : true,
useBatch : false
})
);
var sPath = "/Customers('ALFKI')/Orders";
var oTable = this.byId("myTable");
var oTemplate = sap.ui.xmlfragment({
fragmentContent : jQuery("#myXMLFragment").html()
});
oTable.bindItems({
path : sPath,
template : oTemplate,
templateShareable : false,
sorter : null,
filters : null,
events : {
change : function (oEvent) {
var oModel, oListBnd, aContexts, i, oObj;
console.log("1. Example: ODataModel.getProperty() does not trigger a request (but here we have the data already)!");
oModel = this.getView().getModel();
console.dir( oModel.getProperty("/Orders(10643)")); //OK
console.dir( oModel.getProperty("/Orders") ); //Not OK
console.dir( oModel.getData("/") ); //DANGER: Could contain different entities!!!!!
console.log("2. Example: Accessing the Data via ListBinding");
oListBnd = oTable.getBinding("items"); // get the ListBinding
//oListBnd = oEvent.getSource(); // this works here inside the change handler
aContexts = oListBnd.getCurrentContexts(); // the the contexts
for(i=0; i<aContexts.length; i++){
oObj = aContexts[i].getObject(); // access the items/objects
console.dir( oObj );
}
}.bind(this)
}
});
}
});
});
//### THE APP: place the XMLView somewhere into DOM ###
sap.ui.xmlview({
viewContent : jQuery("#myXmlView").html()
}).placeAt("content");
});
</script>
</head>
<body class="sapUiBody">
<div id="content"></div>
</body>
</html>
Hi Just declare this is manifest
"models": {
"createMod": {
"preload": true,
"dataSource": "CreateService",
"settings": {
}
}
and Try to Access by Controller using.
var oModelCheck = that.getOwnerComponent().getModel("createMod");

Get selected item from sap.m.Select from a sapui5 table column

I am using sap.m.Table, where I have 3 columns, as sap.m.text, sap.m.setect and the last one is button.
My model code
var oModel = new sap.ui.model.odata.OData("url");
sap.ui.getCore().setModel(oModel ,"data");
Table view code(cells)
var oTemplate = new sap.m.ColumnListItem({
cells : [
new sap.m.Text({
text: "{data>Address}"
}),
new sap.m.Select({
id:"sel",
items: {
path: "data>/OPERATORS", // this is a diffent table
template: new sap.ui.core.Item({
text: "{data>firstName} {data>lastName}"
})
},
forceSelection: false
}),
new sap.m.Button({
text : "Start",
press : [oController.onPressStart, oController]
})
]
});
oTable.bindItems("data>/ORDR", oTemplate); //differnt table
Working fine, getting all required data on the specific table.(Notice first column is coming from ORDR table and second one is coming from OPERATORS table).
Now on button click I wanted the specific row data. My code as follows -
onPressStart : function(oEvent){
var obj = oEvent.getSource().getBindingContext("data").getObject();
},
"obj" gives me ORDR table row objects(where I pressed the button).
Now I also want the value I will select on the dropdown box. How to get it.
Please suggest, Thank you
JSbin Link - http://jsbin.com/quhomoloqo/edit?html,console,output
See this working example:
Please note how (for the sake of this question) created two models:
One named 'orig' which holds your original OPERATOR and ODRD data, and
one named 'data' which holds a copy of the OPERATOR data, with an added Address property.
See the view code on how the two models are used (the new one for the table, the old one for populating the dropdown)
sap.ui.controller("view1.initial", {
onInit : function(oEvent) {
},
onAfterRendering : function() {
// your original model
var oModel = new sap.ui.model.json.JSONModel();
var oData = {
"ODRD":[
{"Address":"UK"},
{"Address":"US"}
],
"OPERATORS":[
{"firstName":"a","lastName":"b"},
{"firstName":"c","lastName":"d"}
]
};
oModel.setData(oData);
this.getView().setModel(oModel, "orig");
// the model you actually need
var oNewModel = new sap.ui.model.json.JSONModel();
var oNewData = oData.OPERATORS.map(function(result) {
return {
firstName : result.firstName,
lastName : result.lastName,
keyToAddress : null
}
})
oNewModel.setData({
"OPERATORS" : oNewData
});
this.getView().setModel(oNewModel, "data");
},
showData : function(oEvent) {
alert(JSON.stringify(oEvent.getSource().getBindingContext("data").getObject()));
}
});
sap.ui.xmlview("main", {
viewContent: jQuery("#view1").html()
})
.placeAt("uiArea");
<script id="sap-ui-bootstrap"
src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_bluecrystal"
data-sap-ui-xx-bindingSyntax="complex"
data-sap-ui-libs="sap.m"></script>
<div id="uiArea"></div>
<script id="view1" type="ui5/xmlview">
<mvc:View
controllerName="view1.initial"
xmlns="sap.m"
xmlns:core="sap.ui.core"
xmlns:mvc="sap.ui.core.mvc" >
<Table id="tbl" items="{data>/OPERATORS}">
<columns>
<Column>
<Text text="First" />
</Column>
<Column>
<Text text="Last" />
</Column>
<Column>
<Text text="ODRD" />
</Column>
<Column>
<Text text="" />
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<Input value="{data>firstName}" />
<Input value="{data>lastName}" />
<Select items="{orig>/ODRD}" selectedKey="{data>keyToAddress}">
<items>
<core:ListItem key="{orig>Address}" text="{orig>Address}" />
</items>
</Select>
<Button text="Show data" press="showData" />
</cells>
</ColumnListItem>
</items>
</Table>
</mvc:View>
</script>