cancel
Showing results for 
Search instead for 
Did you mean: 

SAC app: updateMembers and checkbox widgets

igladyshev
Explorer
0 Kudos

I'm trying to use updateMembers() in my app to manage property values of a dimension Dim1 in my planning model.

For this I use a checkboxgroup widget where Selected Items should pass 'X' value to the property Flag of a corresponding Member, and NotSelected Items correspond to the empty '' values.

There is a tab, a checkboxgroup and a button in my app.

I use following code in canvas onInit script to fill checkboxgroup with initial items from Dim1

MemberArray = MyModel.getMembers("Dim1");
for(var k = 0; k < MemberArray.length; k++) 
	{
	//transfer all CP to ChBox	
	CheckboxGroup_1.addItem(MemberArray[k].id, MemberArray[k].description);
	if (MemberArray[k].properties["Flag"] === "X") 
		{	
		SelStrArray.push(MemberArray[k].id);	
		}
	CheckboxGroup_1.setSelectedKeys(SelStrArray);		
	};

I use following code in Button onClick script to synchronize tab and checkboxgroup:

Application.showBusyIndicator();
//clean up all property values
MemberArray = MyModel.getMembers("Dim1");
for(var k = 0; k < MemberArray.length; k++) 
	{
		Member = ({ id: MemberArray[k].id,
					 properties: { Flag: "" 							 
								 }});
		AllMemberArray.push(Member);		
	};
if ( AllMemberArray.length > 0 ) 
	{
		MyModel.updateMembers( "Dim1", AllMemberArray );
	};
//fill selected property values
SelStrArray = CheckboxGroup_1.getSelectedKeys();
for(var i = 0; i < SelStrArray.length; i++) 
	{
		Member = ({ id: SelStrArray[i],
					 properties: { Flag: "X" 							 
								 }});
		SelMemberArray.push(Member);
	};
if ( SelMemberArray.length > 0 ) 
	{
		MyModel.updateMembers( "Dim1", SelMemberArray );	
	};
Table_1.getDataSource().refreshData();
Application.hideBusyIndicator();

Unfortunately, the app works as expected only after the first click on the Button. All subsequent clicks don't remove 'X' from property values, but are only able to add them.

I'm not experienced in JavaScript, so I could misinterpret some syntax, or some used APIs are generally not working in SAC...

Please help to understand. I would appreciate to know other possible scenarios allowing to manage Member Properties from EndUser perspective in the App.

Accepted Solutions (1)

Accepted Solutions (1)

N1kh1l
Active Contributor

igladyshev

Ok The issue is that your variable SelMemberArray does not get emptied out after the dimension update. It still has the old members from first run. I just adjusted the second code block as below and it works as expected. I have just re instantiated the SelMemberArray with a fixed None member which is neither root nor has parent. I could not find a quick way to clear out the array.

Script variables used: The ones in red are array. All are of type planningmodel member.

Application.showBusyIndicator();
//clean up all property values
var ds=Table_1.getDataSource();
Application.refreshData([ds]);
var SelStrArray= ArrayUtils.create(Type.string);
SelStrArray=[""];
SelMemberArray=[{id:"NONE",properties: { Flag: "" }}]; // Re assigning the member with a fixed id None.
var MemberArray1 = MyModel.getMembers("SAP_CEP_SALESORG");


for(var k = 0; k < MemberArray1.length; k++) 
	{
		 Member = ({ id: MemberArray1[k].id,
					 properties: { Flag: "" 							 
								 }});
		AllMemberArray.push(Member);		
	};

if ( AllMemberArray.length > 0 ) 
	{
		var result=MyModel.updateMembers("SAP_CEP_SALESORG",AllMemberArray);
	};
console.log(AllMemberArray);
if(result){
	Application.showMessage(ApplicationMessageType.Success,"Flag set to blank");
}
Application.refreshData([ds]);
//fill selected property values
SelStrArray = CheckboxGroup_1.getSelectedKeys();

for(var i = 0; i < SelStrArray.length; i++) 
	{
		selMember = ({ id: SelStrArray[i],
					 properties: { Flag: "X" 							 
								 }});
		SelMemberArray.push(selMember);
	};
console.log(SelMemberArray);
if ( SelMemberArray.length > 0 ) 
	{
	var update=	MyModel.updateMembers( "SAP_CEP_SALESORG", SelMemberArray );	
	};
if(update){
	Application.showMessage(ApplicationMessageType.Success,"Flag set to X");
}
Application.refreshData([ds]);
Table_1.getDataSource().refreshData();

Application.hideBusyIndicator();

Output:

On Initialization

Update based on checkbox selection

Hope this helps !!

Please upvote/accept if this helps you

Nikhil

Answers (3)

Answers (3)

igladyshev
Explorer
0 Kudos

Thank you, Nikhil, for your fast response and such a detailed analysis. Yes, not cleaning up an array was a reason of this behaviour. And thanks for your script, will know now these tricks with consol.log and .showmessage allowing to "debug" the scripts. We all transform form ABAP'ers to JavaScript'ers this way soon 🙂

I'll allow myself one small question more.

I tried to show ID and Description of Dim1 in the CheckBoxGroup using this script below, but only description is shown for some reason - any thoughts why is it so?

CheckboxGroup_1.addItem(InitMemberArray[k].id, InitMemberArray[k].description);
N1kh1l
Active Contributor

igladyshev

Widgets like Dropdowns, Checkbox group show description if they are available. If you want to show id and description, you can set description to id+"-"+description.

CheckboxGroup_1.addItem(MemberArray[k].id, MemberArray[k].id+"-"+MemberArray[k].description);

Nikhil


igladyshev
Explorer
0 Kudos

Hi,

I adopted the script as you propose (with one remark that there is no .refresh function and I used .refreshData). But it is the same situation. App works as expected only at the first click on the Button, subsequent clicks do not clean up 'X' anymore.

It seems that updatemembers() can commit results to backend only after a function executed fully, so only last updatemembers() is considered in my case.

I have split 'clean up' and 'fill' parts into 2 buttons, and it works well (but I need to click 2 buttons in right sequence each time now...).

Is there any commit() function I could use here? Or any other way to use multiple updatemembers() within a function?

N1kh1l
Active Contributor
0 Kudos

igladyshev

igladyshevNot sure if I understood it right

There is code (your first code snippet) block in on initialization event which read all member of the dimension into the checkbox group and selects the members where property value (flag)= "X"

Next on click of the button, you read all the members of the dimension and set its flag attribute to "". I would suggest you use different variable to read the members here. After every dimension update Refresh the data source using the below code

var ds=Table_1.getDataSource();
Application.refresh([ds]);

Now you read the members selected in the checkbox group and update its flag attribute value to "X". Refresh the application again using the above code.

Now you should ideally repopulate your checkbox group again by first clearing all its members.

Nikhil