cancel
Showing results for 
Search instead for 
Did you mean: 

SAP UI5 - Search JSON model/file with Value from Input Control

kottiyil_ramnath
Participant
0 Kudos

Hi UI5 Experts,

I am new to UI5 and any thoughts are welcome and appreciated.

I have Input control in a Form container. it will have a value when the screen is rendered. Now, depending upon this value, I want to do a search in a JSON file/model and get the corresponding list items.

Once the list is fetched, it should be bound to a Select Control of a table.

Details:

1. I have loaded the JSON file in a JSON model in onInit() function of the controller - Done

2. Get the soldto value from Input control - Done

3. Use this value, do a search in Json model to get the corresponding spath/context - Done (Thanks to sebastian.kielhorn - See below for answer)

4. Bind Aggregation of the context to Select control of Table - Done (Thanks to sebastian.kielhorn - See below for answer)

5. Using UI5 version1.38.40

JSON Sample:

{ "customernetwork": [{ "soldto": "100011", "list": [{ "network_key": "800059" }, { "network_key": "800077" }, { "network_key": "800089" }, { "network_key": "800156" } ] }, { "soldto": "100029", "list": [{ "network_key": "800109" } ] }, { "soldto": "100055", "list": [{ "network_key": "800196" }, { "network_key": "800075" } ] } ] }

Thanks for your help on this.

Accepted Solutions (1)

Accepted Solutions (1)

former_member221786
Active Participant
0 Kudos

Maybe this is what your looking for?!

onChangeInput: function(oEvent) {
	let sSoldToValueFromInput = oEvent.getParameter("value");
	let oModel = this.getView().getModel("yourModelName");


	let iIndex = oModel.getProperty("/customernetwork").findIndex(
		oObject => oObject.soldto === sSoldToValueFromInput );


	let oSelect = this.getView().byId("idOfYourSelectBox");
	oSelect.bindItems({
		path: "yourModelName>/customernetwork/" + iIndex + "/list",
		template: new sap.ui.core.Item({
			key: "{yourModelName>network_key}",
			text: "{yourModelName>network_key}"
		})
	});
}

Hope this helps!

kottiyil_ramnath
Participant
0 Kudos

Thanks sebastian.kielhorn,

Few more details,

Point 3: I did a loop through the model data to get the index. But yes, your single line of code helped and looks more efficient.

Point 4: I did try to put your code but it's not binding the items, I think we are missing something but looks like we are close, So let me put a few more details on it,

My table fragment has this select control on it,

If I put the hardcoded binding like this in select control,

--------------------------------

<Select id = "idnetwork" forceSelection="false" autoAdjustWidth= "true" items="{path: 'customernetworks>/customernetwork/0/list'}" change="setIbwNetId">

<core:Item key="{customernetworks>network_key}" text="{customernetworks>network_key}" />

</Select>

It populates the data from that model correctly.

-------------------------------

But I don't want the hardcoded binding instead do a search based on a soldto value and bind items to this select control which you are already aware of.

a. If i am replacing the binding at view/fragment to controller, how should i change the code, should it be,
<Select id = "idnetwork" forceSelection="false" autoAdjustWidth= "true" change="setIbwNetId" />

b. Is the this.getView().byId("idnetwork"); not working??

Thanks for your help on this.

former_member221786
Active Participant

If you have an Input Control in your table per line then you should do something like:

onChangeInput: function(oEvent) {
	let oSelect = oEvent.getSource().getParent().getItems()[x];
	...
	
}

If you have one Input Control and want to bind the result to every Select Control you should do:

onChangeInput: function(oEvent) {
	let sSoldToValueFromInput = oEvent.getParameter("value");
	let oModel = this.getView().getModel("yourModelName");

	let oFilterObj = oModel.getProperty("/customernetwork").filter(
		oObject => oObject.soldto === sSoldTOValueFromInput);
	
	if (oFilterObj.length > 0) {
		this.getView().setModel(new sap.ui.model.json.JSONModel(oFilterObj[0].list), "yourSecondModelName");
	} //Binding is done in XML
}

Hope this helps!

kottiyil_ramnath
Participant
0 Kudos

Thanks sebastian.kielhorn,

It Worked !!! 😄

Few conclusion details,

Yes, I had one input control, but there is no event on the control. During the initial rendering, it should load everything (Data from both models to its appropriate controls).

I did a small change

From,

if (oFilterObj.length > 0) {
		this.getView().setModel(new sap.ui.model.json.JSONModel(oFilterObj[0].list), "yourSecondModelName");
	} 

To,

if (oFilterObj.length > 0) {
		this.getView().setModel(new sap.ui.model.json.JSONModel(oFilterObj[0]), "yourSecondModelName");
	} 

Thanks once again. Closing this thread and will award points if applicable.

Answers (1)

Answers (1)

ThorstenHoefer
Active Contributor
0 Kudos

Hi,

ich you change the value in the input control, you can handle the change event to filter the binding.

var oSelect = this.getView().byId(...);
var oBinding = oSelect.getBinding("items");

var _sValue = ....

oBinding.filter([ new Filter("soldto", FilterOperator.Contains, sValue)] , FilterType.Application); 
kottiyil_ramnath
Participant
0 Kudos

Thanks xtrnhfo,

There is no event triggered to filter the binding. This binding should happen at rendering the screen with data.

I use 2 models, 1 base model which has all data, and another one for this select control whose JSON data is provided above.

Thanks for your help on this.

ThorstenHoefer
Active Contributor
0 Kudos

You can also add the filer in the binding like:

oSelect.bindItems({
		path: "yourModelName>/customernetwork/",
filters: [ new Filter("soldto", FilterOperator.Contains, sValue)],
template: new sap.ui.core.Item({ key: "{yourModelName>network_key}", text: "{yourModelName>network_key}" }) });