SAPUI5 Filter Bar Get filter values for each filter item in the filter bar - sapui5

I have a filter bar with multiple filter items and I need to get the selected/typed values for each filter item in the onSearch event. I've tried but unable to figure out a way of getting all filter data for all the filter items.
<fb:FilterBar reset="onReset"
search="onSearchFilterbar"
showRestoreButton="true"
showClearButton="true"
filterBarExpanded="false"
id="userFilterBar">
<fb:filterItems>
<fb:FilterItem name="A" label="User">
<fb:control>
<Select id="slcUser" forceSelection="false"
items="{ path: 'sysusers>/Users' , sorter: { path: 'Name' } }" >
<core:Item key="{sysusers>Name}" text="{sysusers>Name}"/>
</Select>
</fb:control>
</fb:FilterItem>
<fb:FilterItem name="B" label="Location">
<fb:control>
<Select id="slcLocation" forceSelection="false"
items="{ path: 'location>/Locations' , sorter: { path: 'Name' } }">
<core:Item key="{location>Name}" text="{location>Name}"/>
</Select>
</fb:control>
</fb:FilterItem>
</fb:filterItems>
</fb:FilterBar>
onsearch:function(oEvent){
oEvent.getSource().getFilterItems()[0];
// But cannot find a way to get the selected data
}

there are a few ways to do this. IMO, the best way is to use model. that's adopting the MVC approach. here is a working example, http://jsbin.com/nudewew/edit?html,output
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta charset="UTF-8">
<title>MVC</title>
<script id="sap-ui-bootstrap" type="text/javascript"
src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_bluecrystal"
data-sap-ui-libs="sap.m,sap.ui.table"
data-sap-ui-xx-bindingSyntax="complex">
</script>
<script id="oView" type="sapui5/xmlview">
<mvc:View height="100%" controllerName="myView.Template"
xmlns="sap.m"
xmlns:fb="sap.ui.comp.filterbar"
xmlns:core="sap.ui.core"
xmlns:mvc="sap.ui.core.mvc">
<fb:FilterBar reset="onReset"
search="onSearchFilterbar"
showRestoreButton="true"
showClearButton="true"
filterBarExpanded="false"
id="userFilterBar">
<fb:filterItems>
<fb:FilterItem name="A" label="User">
<fb:control>
<Select id="slcUser" forceSelection="false" selectedKey="{selection>/user}"
items="{ path: 'sysusers>/Users' , sorter: { path: 'Name' } }" >
<core:Item key="{sysusers>Name}" text="{sysusers>Name}"/>
</Select>
</fb:control>
</fb:FilterItem>
<fb:FilterItem name="B" label="Location">
<fb:control>
<Select id="slcLocation" forceSelection="false" selectedKey="{selection>/location}"
items="{ path: 'location>/Locations' , sorter: { path: 'Name' } }">
<core:Item key="{location>Name}" text="{location>Name}"/>
</Select>
</fb:control>
</fb:FilterItem>
</fb:filterItems>
</fb:FilterBar>
</mvc:View>
</script>
<script>
sap.ui.define([
'jquery.sap.global',
'sap/ui/core/mvc/Controller',
'sap/ui/model/json/JSONModel'
], function(jQuery, Controller, JSONModel) {
"use strict";
var oController = Controller.extend("myView.Template", {
onInit: function() {
var oView = this.getView();
oView.setModel(new JSONModel({
user: "",
location: ""
}), "selection");
oView.setModel(new JSONModel({
Users: [
{Name: "johnDoe"},
{Name: "maryAnn"}
]
}), "sysusers");
oView.setModel(new JSONModel({
Locations: [
{Name: "London"},
{Name: "Paris"}
]
}), "location");
},
onSearchFilterbar: function(oEvent) {
console.log(this.getView().getModel("selection").getData());
}
});
return oController;
});
var oView = sap.ui.xmlview({
viewContent: jQuery('#oView').html()
});
oView.placeAt('content');
</script>
</head>
<body class="sapUiBody" role="application">
<div id="content"></div>
</body>
</html>

The value of items is on Parameters of de Event.
oEvent.getParameter('0').selectionSet
It's a array with each Control of filterbar you can use:
oEvent.getParameter('0').selectionSet[0].getValue()

There are a few ways to do this.. but with your current code, I would suggest the following:
The short answer to your question:
The FilterBar has a method determineControlByFilterItem you can use to get the control for the filter item, which you can then use to get the selected value.
var oFilterItem = oEvent.getSource().getFilterItems()[0];
var oControl = oFilterBar.determineControlByFilterItem(oFilterItem);
var sSelectedValue = oControl.getSelectedKey();
Be cautious, though, when hard coding array indexes like this. For a more complete solution to your problem, I've suggested a full approach below.
The long answer if you want to use the filter bar to filter a result set:
First, make sure the names of your filter items align to the name of the property you want to filter by. So in your case, your filter items are named "A" and "B"... I suggest you change these to match the property name you want to filter by. Assuming that the names of the properties you want to filter by are "User" and "Location":
<FilterItem name="User" label="User">
...
<FilterItem name="Location" label="Location">
...
Then in your controller, you can use those names to build an array of sap.ui.model.Filter objects that you can use to filter your result set.
onSearch: function(oEvent) {
//get the filter bar from the event
var oFilterBar = oEvent.getSource();
//get the filter items from the filter bar
var aFilterItems = oFilterBar.getFilterItems();
//map the array of FilterItems to a new array of sap.ui.model.Filter objects
var aFilters = aFilterItems.map(function(oFilterItem) {
//get the filter item name (which is now the same as the filter property name)
var sFilterName = oFilterItem.getName();
//use the filter bar to get the control for the filter item
var oControl = oFilterBar.determineControlByFilterItem(oFilterItem);
//use the control to get the selected value (selected key)
var sSelectedValue = oControl.getSelectedKey();
//use the filter item/property name and the selected value to create a new sap.ui.model.Filter
var oFilter = new sap.ui.model.Filter(sFilterName, "EQ", sSelectedValue);
//return the Filter object to the new array
return oFilter
});
//use the array of sap.ui.model.Filter objects to filter your table
//if you're using a responsive table (sap.m.Table), use:
this.getView().byId("yourTableId").getBinding("items").filter(aFilters);
//or if you're using a grid table (sap.ui.table.Table), use:
this.getView().byId("yourTableId").getBinding("rows").filter(aFilters);
}
The reason I suggest this approach as opposed to others, is because it scales nicely. Say, for example, that you want to add a third Select control to filter by, you simply need to add a new <FilterItem name="NewFilterProperty" label="New Filter Property">. Because we didn't hard code anything into the event handler, it will still work without any additional changes.
The only thing to lookout for is if you use different types of controls in your FilterBar. So, for example, if you added an <Input> instead of a <Select>, you'll need to adjust the logic of your event handler to handle this.
I usually do something like this:
onSearch: function(oEvent) {
var oFilterBar = oEvent.getSource();
var aFilterItems = oFilterBar.getFilterItems();
var aFilters = aFilterItems.map(function(oFilterItem) {
var sFilterName = oFilterItem.getName();
var oControl = oFilterBar.determineControlByFilterItem(oFilterItem);
var sValue;
if (oControl.getMetadata().getName() === "sap.m.Select") {
sValue = oControl.getSelectedKey();
} else if (oControl.getMetadata().getName() === "sap.m.Input") {
sValue = oControl.getValue();
}
var oFilter = new sap.ui.model.Filter(sFilterName, "EQ", sValue);
return oFilter;
});
}

Related

How to disable sap.m.Select when only one selection item left

I made an example for this question with the following logic:
A dropdown (sap.m.Select) has 2 options:
But whenever a checkbox above it is checked it only has one option left:
In that case I don't need any of this anymore:
So I found out, that the property editable="false" does exactly what I want in this case:
...but I don't know how to set editable dynamically depending on the current number of options.
Here's the full example:
https://jsfiddle.net/mb0h8v1s/1/
Since you are using a JSONModel you can say something like
editable="{= ${options>/arr1}.length > 1 }"
This is called Expression Binding and lets you use basic JavaScript within your binding.`
This assumes that you always use the same list and change the content of your list once the CheckBox is triggered and not rebind the list.
View:
<!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">
<Shell>
<Page id="mainPage" showHeader="false">
<FlexBox id="flex" justifyContent="Center" alignItems="Center" direction="Column">
<CheckBox
text="Only 1 option"
selected="{path:'options>/cbx_val'}"
/>
</FlexBox>
</Page>
</Shell>
</mvc:View>
</script>
<body class="sapUiBody">
<div id="content"></div>
</body>
JavaScript:
sap.ui.getCore().attachInit(function() {
"use strict";
sap.ui.controller("MyController", {
onInit: function() {
console.log("INITIALIZING!");
var arr1 = [{
id: "1",
name: "1st option"
}];
var arr2 = arr1.concat([{
id: "2",
name: "2nd option"
}]);
var oModel = new sap.ui.model.json.JSONModel({
cbx_val: false,
arr1: arr1,
arr2: arr2
});
this.getView().setModel(oModel, "options");
var selectVal = new sap.m.Select({
id: "selectField",
selectedKey: '',
editable: true,
enabled: "{= !${options>/cbx_val}}"
});
var selectLbl = new sap.m.Label({
text: "Select:",
labelFor: selectVal,
});
var selectLogicListener = new sap.m.Text({
visible: false,
text: {
parts: ['options>/cbx_val'],
formatter: function(bVal) {
var result = "options>/arr2";
if (bVal) {
result = "options>/arr1";
}
console.log(result);
selectVal.bindItems({
path: result,
template: new sap.ui.core.Item({
key: "{options>id}",
text: "{options>name}"
})
});
}
}
});
this.byId("flex").addItem(selectLbl);
this.byId("flex").addItem(selectVal);
this.byId("flex").addItem(selectLogicListener);
}
});
sap.ui.xmlview({
viewContent: jQuery("#myView").html()
}).placeAt("content");
});

Is it possible to add Binding change event to a component in XML view?

I have a component in SAPUI5 where I need to listen to changes in the binding (Binding.change event). At the moment I'm adding a listener to the Binding in modelContextChange like this:
function onModelContextChange(oEvent){
var oSelect = oEvent.getSource();
var binding = oSelect.getBinding("items");
if(binding){
binding.attachChange(onDataChange, oSelect);
}
}
However this causes all kinds of weird problems, because modelContextChange could be fired multiple times. It would be better to to this in the XML view. I've tried code like this, but it doesn't work.
<Select items="{ path: 'project>/data/', change:'onDataChange' templateShareable: false">
<core:Item key="{project>Id}" text="{project>Parameter}"/>
</Select>
Any recommendations how to do this?
I just came across the problem, too. I solved it in that way:
<Select items="{
path: 'project>/data',
events: {
change: '.onDataChange'
},
templateShareable: false
}">
You can pass an events object to the binding and use the available bindings (e.g. v2.ODataListBinding). Note that you have to use a dot before your function name (.onDataChange). In your controller you can add the function:
onDataChange: function(oEvent) {
// Your implementation...
},
If I remember well from the JS Views, I think it is like this:
<Select items="{ path: 'project>/data/', events: {change:'onDataChange'}, templateShareable: false}">
This is for listening to the Model "change" events.
If you want to listen to the "change" event in the Select control, this is when the user selects a different value in the dropdown, it is like this:
<Select items="{ path: 'project>/data/', templateShareable: false}" change="onDataChange">
EDIT:
Using "modelContextChange" event.
<Select items="{ path: 'project>/data/', templateShareable: false}" modelContextChange="onDataChange">
here is an example
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</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-xx-bindingSyntax="complex"
data-sap-ui-libs="sap.m"></script>
<style type="text/css">
.sapMObjLTitle {
cursor: pointer;
}
</style>
<!-- XML-based view definition -->
<script id="oView" type="sapui5/xmlview">
<mvc:View height="100%" controllerName="myView.Template"
xmlns="sap.m"
xmlns:core="sap.ui.core"
xmlns:mvc="sap.ui.core.mvc">
<Select change="onDataChange" items="{ path: 'project>/data', templateShareable: false}">
<core:Item key="{project>Id}" text="{project>Parameter}"/>
</Select>
</mvc:View>
</script>
</head>
<body class="sapUiBody">
<div id='content'></div>
</body>
</html>
sap.ui.define([
'jquery.sap.global',
'sap/ui/core/mvc/Controller',
'sap/ui/model/json/JSONModel'
], function(jQuery, Controller, JSONModel) {
var ListController = Controller.extend("myView.Template", {
onInit: function(oEvent) {
var oView = this.getView();
oView.setModel(new JSONModel({
data: [{
Id: "1",
Parameter: "One"
}, {
Id: "2",
Parameter: "Two"
}]
}), "project");
},
onDataChange: function() {
alert("changed")
}
});
return ListController;
});
// Instantiate the View and display
var oView = sap.ui.xmlview({
viewContent: jQuery('#oView').html()
});
oView.placeAt('content');
https://jsbin.com/zufurav/edit?html,js,output
Note: the change attribute in your XML is incorrect
I managed to get the binding change event with this set to the element that I needed by attaching a modelContextChange to the element and handling attaching the change event to the binding in there. Here's the code from the view controller:
modelContextChange: function(oEvent) {
var oElement = oEvent.getSource();
var binding = oElement.getBinding("items");
if (binding) {
//Binding change event could already be attached, detach it first, if it's there
binding.detachChange(this.onBindingChange, oSelect);
binding.attachChange(this.onBindingChange, oSelect);
// Beacause I used this inside a sap.ui.table.Treetable,
// in some cases binding changes occur without the binding change event firing.
// Manually fire the binding change just in case
// YMMV
binding.refresh(true);
}
},
onBindingChange: function() {
//The code that needs to run at binding change
//"this" is set to the correct element
//I specifically needed to add one element in front of other items in a sap.m.Select
var items = this.removeAllItems();
this.addItem(new sap.ui.core.Item({
key: 0,
text: "< Inherit >"
}));
items.forEach(function(item) {
this.addItem(item);
}, this);
}

add second filter without removing the existing ones

Hi i have a searchfield with this code behind it:
onSearch : function (oEvent) {
if (oEvent.getParameters().refreshButtonPressed) {
// Search field's 'refresh' button has been pressed.
// This is visible if you select any master list item.
// In this case no new search is triggered, we only
// refresh the list binding.
this.onRefresh();
} else {
var andFilter = [];
var sQuery = oEvent.getParameter("query");
if (sQuery && sQuery.length > 0) {
// add filters
var oTableSearchState = [];
oTableSearchState = [new Filter("Supplier", FilterOperator.Contains, sQuery), new Filter("BusArea", FilterOperator.Contains, sQuery), new Filter("CostCenter", FilterOperator.Contains, sQuery),
new Filter("FuncArea", FilterOperator.Contains, sQuery)];
andFilter.push(new Filter(oTableSearchState, false));
}
this._applySearch(andFilter);
}
},
And a filter button that should add aditional filters. Something like this:
onSetFilter : function(oEvent) {
var andFilter = [];
andFilter.push(new Filter("BusArea", FilterOperator.EQ, "5000"));
this._applySearch(andFilter);
},
But of course the "BusArea" part should be dependent on what filters are selected. It could be more than 1 filter. the _applySearch function looks like this:
_applySearch: function(andFilter) {
var oViewModel = this.getModel("worklistView");
this._oTable.getBinding("items").filter(andFilter, true);
// changes the noDataText of the list in case there are no filter results
if (andFilter.length !== 0) {
oViewModel.setProperty("/tableNoDataText",
this.getResourceBundle().getText("worklistNoDataWithSearchText"));
}
}
the problem is that when i add a filter via the filter button, the filters from the searchbar disappear and the other way arround. how can i change my code so that i can add the filters without removing the existing ones?
One solution is to get the Filters from the binding info and push back together with the new Filter using and.
this._oTable.getBindingInfo("items").filters.aFilters;
After our conversation on the chat, I have made this snippet using a global model.
https://jsbin.com/pewavuhonu/edit?html,output
The ComboBox and the Button simulates your Dialog.
The input simulates the SearchField
Both are binded against the global "filtersModel", and both call the _calculateFilters() function when submiting the info
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<meta charset="utf-8">
<title>MVC with XmlView</title>
<!-- Load UI5, select "blue crystal" theme and the "sap.m" control library -->
<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-libs='sap.m'
data-sap-ui-xx-bindingSyntax='complex'></script>
<!-- DEFINE RE-USE COMPONENTS - NORMALLY DONE IN SEPARATE FILES -->
<!-- define a new (simple) View type as an XmlView
- using data binding for the Button text
- binding a controller method to the Button's "press" event
- also mixing in some plain HTML
note: typically this would be a standalone file -->
<script id="view1" type="sapui5/xmlview">
<mvc:View xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" controllerName="my.own.controller">
<Panel headerText="Filters">
<VBox>
<HBox>
<Label text="Filter by Customer:" class="sapUiSmallMarginTop sapUiSmallMarginEnd"/>
<ComboBox id="comboBox" selectedKey="{filtersModel>/customerFilter}">
<items>
<core:Item key="VINET" text="VINET" />
<core:Item key="TOMSP" text="TOMSP" />
<core:Item key="HANAR" text="HANAR" />
<core:Item key="VICTE" text="VICTE" />
<core:Item key="SUPRD" text="SUPRD" />
</items>
</ComboBox>
<Button text="Apply this Filter" press="_calculateFilters"></Button>
</HBox>
</VBox>
<VBox>
<HBox>
<Input value="{filtersModel>/shipAddressFilter}" id="input" submit="_calculateFilters" width="500px" placeholder="Filter by ShipAddress: Write and enter for filtering"/>
</HBox>
</VBox>
</Panel>
<Panel>
<List id="list" items="{/Orders}">
<StandardListItem title="{CustomerID}" info="{ShipAddress}"/>
</List>
</Panel>
</mvc:View>
</script>
<script>
// define a new (simple) Controller type
sap.ui.controller("my.own.controller", {
onInit: function(){
var oFiltersModel = new sap.ui.model.json.JSONModel();
sap.ui.getCore().setModel(oFiltersModel, "filtersModel");
},
_calculateFilters: function(){
var oSelect = this.getView().byId("comboBox"),
oListBinding = this.getView().byId("list").getBinding("items"),
oFiltersModel = sap.ui.getCore().getModel("filtersModel"),
oCustomerFilterValue = oFiltersModel.getProperty("/customerFilter"),
oShipAddressValue = oFiltersModel.getProperty("/shipAddressFilter"),
oFilters = [];
if(oCustomerFilterValue){
oFilters.push(new sap.ui.model.Filter("CustomerID", "EQ", oCustomerFilterValue));
}
if(oShipAddressValue){
oFilters.push(new sap.ui.model.Filter("ShipAddress", "Contains", oShipAddressValue));
}
oListBinding.filter(oFilters);
}
});
/*** THIS IS THE "APPLICATION" CODE ***/
// create some dummy JSON data
var data = {
actionName: "Say Hello"
};
// instantiate the View
var myView = sap.ui.xmlview({viewContent:jQuery('#view1').html()}); // accessing the HTML inside the script tag above
// create a Model and assign it to the View
var uri = "https://cors-anywhere.herokuapp.com/services.odata.org/Northwind/Northwind.svc"; // local proxy for cross-domain access
var oModel = new sap.ui.model.odata.ODataModel(uri, {
maxDataServiceVersion: "2.0"
});
myView.setModel(oModel);
// put the View onto the screen
myView.placeAt('content');
</script>
</head>
<body id='content' class='sapUiBody'>
</body>
</html>

How to push the data in XML view into the newly created JSON model?

How to push the data in XML view into the newly created JSON model? I have created the comboBox and retrieved the data from JSON model and also created the text area when I select the item in combo box and insert data into the text area and submit a button both the data should be pushed to newly created JSON model in sapweb ide ui5
page.view.xml:
<mvc:View height="100%" controllerName="pro.controller.Page" xmlns:core="sap.ui.core" xmlns:l="sap.ui.layout" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m">
<Page title="{i18n>title}">
<content>
<l:VerticalLayout>
<ComboBox items="{ path: '/ProductCollection', sorter: { path: 'Name' } }">
<core:Item text="{Name}" /> </ComboBox>
<TextArea value="" rows="8" />
<Button type="Accept" text="Submit" press="onPress" /> </l:VerticalLayout>
</content>
</Page>
</mvc:View>
page.controller.js
sap.ui.define([
'jquery.sap.global',
'sap/ui/core/mvc/Controller',
'sap/ui/model/json/JSONModel'
], function(jQuery, Controller, JSONModel) {
"use strict";
var PageController = Controller.extend("pro.controller.Page", {
onInit: function() {
// set explored app's demo model on this sample
var oModel = new JSONModel(jQuery.sap.getModulePath("pro", "/model/model.json"));
this.getView().setModel(oModel);
}
});
return PageController;
});
add a 'key' attribute to the combobox item. Also give the combobox and teaxarea some IDs.
<ComboBox id="selectBox" items="{ path: '/ProductCollection', sorter: { path: 'Name' } }">
<core:Item key="{Naame}" text="{Name}" /> </ComboBox>
<TextArea id="textArea" value="" rows="8" />
On click of submit, get the selected values from the combobox and text area and push them into the model. I assume that you wanted to push this new data to the existing model and also your existing model is an array of objects.
sap.ui.define([
'jquery.sap.global',
'sap/ui/core/mvc/Controller',
'sap/ui/model/json/JSONModel'
],function(jQuery, Controller, JSONModel) {
"use strict";
var PageController = Controller.extend("pro.controller.Page", {
onInit: function() {
var oModel = new JSONModel(jQuery.sap.getModulePath("pro", "/model/model.json"));
this.getView().setModel(oModel);
},
onPress: function() {
//get the value of the selected item in the combobox
var selectedVal = this.getView().byId("selectBox").getSelectedKey();
//get the textarea value
var textAreaVal = this.getView().byId("textArea").getValue();
this.getView().getModel().oData.push({
key: selectedVal,
value: textAreaVal
});
}
});
return PageController;
});

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>