cancel
Showing results for 
Search instead for 
Did you mean: 

SAP MDK bind data to the List picker control from the rule

learner1
Explorer
0 Kudos

Hi Experts, @bill_froelich 

I am trying to call the OData from the Rule and bind the results to List Picker control. Rule is executing when the page is loaded and  getting the error as no Data providers exists, it's due to the Page is loaded before the Service is initialized. Now I am calling the OData services after the Success Action of the InitializeOnline.action and setting the data to the ListPicker using the setPickerItems(items). 

But this is making the list screen hanging as the screen is loading all the records that are set using setPickerItems method and no paging working here. I don't want to bind the entityset as a target to the list picker as I want to use the search functionality and filter the values within the list picker results screen without making an Odata call again when I type a text. 

Is there any option to call the OData after the click of ListPicker, store all the records from the response in client data and bind the string collection or object collection to List Picker without loosing the paging feature

#MDK, #SAP MDK ListPicker

bill_froelich
Product and Topic Expert
Product and Topic Expert
0 Kudos
Is the list picker on the main page of the application?

Accepted Solutions (0)

Answers (6)

Answers (6)

learner1
Explorer
0 Kudos

Hi @bill_froelich,

To the first list picker I am setting the list from the Rule, values are defaulting when the Odata initialised successfully.

clientAPI.read("/OrderApp/Services/ORDERSERV.service", 'Orders', [],  '$top=5000').then(function(oData){
        let data = oData._array;
        if(data){
            data = data.map(({Code, Desc}) => ({
                DisplayValue: Code + ': ' + Desc ,ReturnValue: Code
            }));
            //clientAPI.getPageProxy().getControls()[0].getControl("ListPickder1").setPickerItems(data); -- Did this to set the data which is loading in the picker items and working
            //clientAPI.getPageProxy().getControls()[0].getControl("ListPickder1").setValue(["I47","I01"]); --- Tried this to default the values for testing. But the values actually defaulted are the 1st item from the list repeated twice as the two values set here
            // clientAPI.getPageProxy().getControls()[0].getControl("ListPickder1").reset(); -- Tried this to call the rule which will execute the Odata and populate 
        }
    });

 

// Defaulting the listpikcer values here
clientAPI.getPageProxy().getControls()[0].getControl("ListPicker1").setValue(arrayOfValues); 
learner1
Explorer
0 Kudos

Hi @bill_froelich 

Here is the metadata of the page.

{
	"Controls": [
		{
			"FilterFeedbackBar": {
				"ShowAllFilters": false,
				"_Type": "Control.Type.FilterFeedbackBar"
			},
			"_Type": "Control.Type.SectionedTable",
			"_Name": "SectionedTable0",
			"Sections": [
				{
					"Separators": {
						"TopSectionSeparator": false,
						"BottomSectionSeparator": true,
						"HeaderSeparator": true,
						"FooterSeparator": true,
						"ControlSeparator": true
					},
					"Controls": [
						{
							"_Type": "Control.Type.FormCell.ListPicker",
							"_Name": "ListPicker1",
							"IsVisible": true,
							"Separator": true,
							"AllowMultipleSelection": true,
							"AllowEmptySelection": true,
							"Caption": "This is bound to string collection",
							"DataPaging": {
								"ShowLoadingIndicator": true,
								"LoadingIndicatorText": "",
								"PageSize": 10000
							},
							"IsSelectedSectionEnabled": true,
							"IsPickerDismissedOnSelection": false,
							"IsSearchCancelledAfterSelection": false,
							"AllowDefaultValueIfOneItem": false,
							"IsEditable": true,
							"FilterProperty": [],
							"Search": {
								"Enabled": true,
								"Placeholder": "Select",
								"Delay": 100
							},
							"PickerItems": []
						},
						{
							"_Type": "Control.Type.FormCell.ListPicker",
							"_Name": "ListPicker2",
							"IsVisible": true,
							"Separator": true,
							"AllowMultipleSelection": true,
							"AllowEmptySelection": true,
							"Caption": "This is bound to Object binding on entityset",
							"DataPaging": {
								"ShowLoadingIndicator": false,
								"LoadingIndicatorText": "",
								"PageSize": 10000
							},
							"IsSelectedSectionEnabled": true,
							"IsPickerDismissedOnSelection": false,
							"IsSearchCancelledAfterSelection": false,
							"AllowDefaultValueIfOneItem": false,
							"IsEditable": true,
							"FilterProperty": [],
							"Search": {
								"Enabled": true,
								"Delay": 100
							},
							"PickerItems": {
								"Target": {
									"Service": "/Search/Services/Search.service",
									"EntitySet": "ORDERTYPES_F4"
								},
								"DisplayValue": "{OrderType}: {Desc}",
								"ReturnValue": "{OrderType}"
							}
						}
					],
					"Visible": true,
					"EmptySection": {
						"FooterVisible": false
					},
					"_Type": "Section.Type.FormCell",
					"_Name": "SectionFormCell0"
				}
			]
		}
	],
	"_Type": "Page",
	"_Name": "Search",
	"Caption": "Search",
	"PrefersLargeCaption": false,
	"ToolBar": {
		"Items": [
			{
				"_Type": "Control.Type.ToolbarItem",
				"_Name": "ToolbarItem1",
				"Caption": "Search",
				"Enabled": true,
				"Visible": true,
				"Clickable": true,
				"ItemType": "Button",
				"Style": "",
				"OnPress": "/Search/Actions/Search.js"
			}
		],
		"Visible": true
	}
}

 I have just renamed the service and captions to publish it here, rest of the code is as it is.  

bill_froelich
Product and Topic Expert
Product and Topic Expert
0 Kudos
How and where are you populating the first list picker that is bound to a string collection?
learner1
Explorer
0 Kudos

Hi @bill_froelich thanks for the reply. I am currently calling OData services for list pickers after service is initialised, these calls would happen irrespective whether list picker clicked or not. This will impact the performance of the UI if making the calls several list pickers. If I set the rule to the list picker then rule getting executed even before the OData service is initialised this is leading the page to load blank screen.

I am setting the default values as an array the to list picker where picker items are bound to the entity set. List picker defaulting the top value from the list always. This works okay where listpicker bound to string collection. 

Ex. 

let orderTypes = ["C","D"];

orderTypeLipickerControl.setValue(orderTypes);

as a result I see two OData calls are triggered immediately as 

call 1: OrderTypesSet?$filter=Type eq 'C'

call 2: OrderTypesSet?$filter=Type eq 'D'

after the data loaded / bound to list picker, orderTypeLipickerControl has two default values (duplicate) AA.

Where 'A' is the first value from the list such as that the list has A, B, C, D. List picker always setting the top value as default value and duplicating as many values set previously. 

bill_froelich
Product and Topic Expert
Product and Topic Expert
0 Kudos
Can you share your page metadata definition?
bill_froelich
Product and Topic Expert
Product and Topic Expert
0 Kudos

You are correct that if the picker is on the main page of your application, the page will be loaded before the Odata service is initialized and you will need to trigger a reset once the service is initialized.  I would recommend having your rule get the picker and call reset() on it to reinitialize the picker.

When using a rule for your picker items there is no paging support.  Even if your rule is reading from Odata, there is no paging support and the rule is expected to return ALL items for the picker.  The reason the picker makes a roundtrip to the backend is because if it is bound to an entity set the picker needs the backend to return the list of matching items since there may be matches that have not yet been paged into the list.  I would recommend setting the MinimumCharacterThreshold and Delay in the picker search settings so the client does not try to get results from the backend each time a key is pressed while typing in the search value.

For setting a default value for the picker, if the Picker Items are bound to an entity set then yes, it will make a call to the backend to get the Display Value and verify the value is in the list of available items.  This again is due to paging since the default value is not guaranteed to be in the first page of data loaded the picker needs the backend call to get this information. If you are using a rule, there should not be a backend call for the default value since the entire list of possible items has already been provided.

bill_froelich
Product and Topic Expert
Product and Topic Expert
0 Kudos
Please note, I have been unable to reproduce the issue you described about the list containing a duplicate value for the default. If you have additional details on that I can investigate further.
learner1
Explorer
0 Kudos

Hi @bill_froelich , Yes I am using online connection for OData service. I am working on iOS with MDK 23.12 client version.

I also found out an issue with defaulting values to list picker as an array, as its converting values to duplicate. For ex. to the list picker when I set ["A","B"], its actually converting them as ["A","A"] and two OData calls are happing with $filter=field eq 'A'. Is it because I am setting the default values before the data is loaded in to list picker?

 

learner1
Explorer
0 Kudos

@bill_froelich yes the listpicker is on the main page. 

bill_froelich
Product and Topic Expert
Product and Topic Expert
0 Kudos

Just to clarify, I assume you are also using an online connection for your Odata service?  Also, what platform are you working on?