cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Browse apps to extend the software in the new JMP Marketplace
Choose Language Hide Translation Bar
fch_jmp
Level II

Update the content of a DisplayBox with an Associate Array when the selection of a ComboBox changes ?

[Version: JMP Pro 16.2.0]
Hello,

I am trying to build an interface window for a script that:

  1. sends the current data table to Python and get user-input values for the parameters,
  2. performs some actions in Python,
  3. adds some columns from a Python DataFrame to the current data table.

I added as attachment the layout I have in mind for the interface.

I haven't figured out yet how to update the content of the parameters that I prompt the user to enter depending on the user-selected option in the ComboBox above.
To make the code easier to maintain and avoid code redundancy (important for me because I plan to have many options in the ComboBox), I would like to store the parameters and their default values in an Associative Array on top of the script. The number of parameters for each option could be different.
I looked at the code of this add-in (https://community.jmp.com/t5/JMP-Add-Ins/Data-visualization-with-t-SNE-and-UMAP/ta-p/177969) but unfortunately, the fields to be displayed and their associated Number Edit Boxes values are hardcoded.

 

Thanks for your help.
Best Regards,
François

#Emmanuel_Romeu
#James_Bark

AA =
Associative Array(
	{
		{"Choice_A", 
			[
			"param_1" => 2,
			"param 2" => 15, 
			"param_4" => .	
			]
		}, 
		{"Choice_B", 
			[
			"param 1" => 2, 
			"param 3" => 10,
			"param 4" => .
			]
		}, 
		{"Choice_C",
			[
			"param 1" => 3, 
			"param 4" => ., 
			"param 6" => 23, 
			"param 7" => 123
			]
		}
	
	}
);

JMP_INTERFACE.png

1 ACCEPTED SOLUTION

Accepted Solutions

Re: Update the content of a DisplayBox with an Associate Array when the selection of a ComboBox changes ?

You can make the dialog modal, as below.

 

To make a recall function, you will need to prevent re-initializing the AAs each time the window is opened, by initializing the AAs in another part of the code, that can be separated from the code used to show the window.

 

Each time the OK button is pressed, in addition to saving the new values to the appropriate AA as is already done, you can save the settings off to global (or, preferably, scoped) variables, and use these variables' values to populate the dialog the next time "recall" is pressed.

 

Names Default To Here( 1 );

AAopt1 = Associative Array( Words( "p1,p2,p3", "," ), {1, 2, 3} );
AAopt2 = Associative Array( Words( "p1,p4", "," ), {1, 10} );
AAopt3 = Associative Array( Words( "p2,p5,p6,p7", "," ), {2, 6, 12, 20} );
MainAA = Associative Array( Words( "option1,option2,option3", "," ), Eval List( {AAopt1, AAopt2, AAopt3} ) );


nw = New Window( "xx", <<modal, << on open(eval(cb << get function) ),
	V List Box(
		cb = Combo Box(
			mainAA << get keys,
			Try( TB << delete );
			tableVLB << append(
				tb = Table Box(
					TbSCB = String Col Box( "parameter", mainAA[cb << get selected] << Get Keys ),
					TbNCEB = Number Col Edit Box( "value", mainAA[cb << get selected] << Get Values )
				)
			);
		),
		tableVLB = V List Box(),
		buttonbox("OK", 
			mainAA[cb << get selected] = Associative Array( TbSCB << get, TbNCEB << get );
			Show( mainAA );
		)
	)
);

View solution in original post

7 REPLIES 7
ih
Super User (Alumni) ih
Super User (Alumni)

Re: Update the content of a DisplayBox with an Associate Array when the selection of a ComboBox changes ?

Hi @fch_jmp ,

 

If I understand your question correctly then I think this does what you are looking for:

 

Names default to here(1);

AA = Associative Array( {
	{"Choice_A", ["param_1" => 2, "param 2" => 15, "param_4" => .]},
	{"Choice_B", ["param 1" => 2, "param 3" => 10, "param 4" => .]},
	{"Choice_C", ["param 1" => 3, "param 4" => ., "param 6" => 23, "param 7" => 123]}
} );


//return a label and 
parambox = function({name,val},
	h list box(
		text box(name),
		nebParam[name] = number edit box(val)
	)
);

updateparams = function({},
	while( !is empty( vlbParams << child ), (vlbParams << child) << delete );
	nebParam = Associative Array();
	for each({{param, value}, i}, AA[cb << GetSelected()],
		vlbParams << append(
			parambox(param, value)
		);
	)
);
		
win = new window("cb test",
	cb = Combo Box(
		AA << Get Keys,
		updateparams();
	),
	vlbParams = v list box(),
	button box("Write to the log",
		for each({{param, value}}, nebParam, print(param || ": " || char(value << get)));
	)
);
cb << set(1);
updateparams();

Note that with this method multiple windows could collide with each other so I would actually use window variables. Try running this once, change your parameters array, and then run it again and note how both windows work independently.

View more...
Names default to here(1);

AA = Associative Array( {
	{"Choice_A", ["param_1" => 2, "param 2" => 15, "param_4" => .]},
	{"Choice_B", ["param 1" => 2, "param 3" => 10, "param 4" => .]},
	{"Choice_C", ["param 1" => 3, "param 4" => ., "param 6" => 23, "param 7" => 123]}
} );


//return a label and 
parambox = function({name,val},
	h list box(
		text box(name),
		window:nebParam[name] = number edit box(val)
	)
);

updateparams = function({},
	while( !is empty( window:vlbParams << child ), (window:vlbParams << child) << delete );
	window:nebParam = Associative Array();
	for each({{param, value}, i}, AA[cb << GetSelected()],
		vlbParams << append(
			parambox(param, value)
		);
	)
);
		
win = new window("cb test",
	window:AA = AA;
	window:cb = Combo Box(
		window:AA << Get Keys,
		updateparams();
	),
	window:vlbParams = v list box(),
	button box("Write to the log",
		for each({{param, value}}, window:nebParam, print(param || ": " || char(value << get)));
	),
	window:cb << set(1);
	updateparams();
);

 

fch_jmp
Level II

Re: Update the content of a DisplayBox with an Associate Array when the selection of a ComboBox changes ?

Hi @ih,

Thanks for your prompt reply.

I took a close look at your script with window variables.

I played with it and made some updates to it.

I still have a few questions/remarks if you don't mind:

  • One issue for me is that the order of the parameters to be entered does not follow the order I put them in the Associative Array.
    I would like to have them in the same order as the one in the AA definition. Is that possible ?
  • Can the layout of the couples (TextBox, Number Edit Box) be improved such that they are aligned in two separated columns (I add a screenshot to illustrate - done using LineUp Box-)
    I also tried to replace the V List Box (window:vlbParam) by a Table Box, without success so far.
  • Can a working "recall" Button Box be easily added to this interface ?
  • Lastly, I added some comment to your updated script to explain what I am trying to do.

Thanks again !

Regards,

François

ih
Super User (Alumni) ih
Super User (Alumni)

Re: Update the content of a DisplayBox with an Associate Array when the selection of a ComboBox changes ?

I haven't kept track of whether all of these are answered in other posts yet, but two thoughts:

 

  • If you want to keep parameters ordered you could use arrays inside your associative array, like this:
    AA = Associative Array( {
    	{"Choice_A", [
    		//Array of here to maintain order
    ["name" => "param_1", "default" => 2], ["name" => "param_2", "default" => 15], ["name" => "param_3", "default" => .], ]} } )
  • You could specify text box and number edit box widths to make everything line up, or you could instead use a table with number col edit boxes.

Re: Update the content of a DisplayBox with an Associate Array when the selection of a ComboBox changes ?

Hi,

 

One relatively efficient way to do this is as follows.

1) Define parameter/value sets in AAs, one AA for each option.

2) Place these AAs in a "main" AA.

3) Use the combobox to select within the "main" AA

4) For any selection, surface a single tablebox (after deleting the current one, if present), whose rows correspond to entries in the relevant option AA.

5) When the "go" button is pressed, it is easy to update the relevant "option" AA with whatever entries have been made, and proceed. Here, the mainAA is written to the log so you can see its contents after each press.

 

Cheers,

Brady

Names Default To Here( 1 );

AAopt1 = Associative Array( Words( "p1,p2,p3", "," ), {1, 2, 3} );
AAopt2 = Associative Array( Words( "p1,p4", "," ), {1, 10} );
AAopt3 = Associative Array( Words( "p2,p5,p6,p7", "," ), {2, 6, 12, 20} );
MainAA = Associative Array( Words( "option1,option2,option3", "," ), Eval List( {AAopt1, AAopt2, AAopt3} ) );

nw = New Window( "xx",
	V List Box(
		cb = Combo Box(
			mainAA << get keys,
			Try( TB << delete );
			tableVLB << append(
				tb = Table Box(
					TbSCB = String Col Box( "parameter", mainAA[cb << get selected] << Get Keys ),
					TbNCEB = Number Col Edit Box( "value", mainAA[cb << get selected] << Get Values )
				)
			);
		),
		tableVLB = V List Box(),
		bb = Button Box( "Go",
			mainAA[cb << get selected] = Associative Array( TbSCB << get, TbNCEB << get );
			Show( mainAA );
		)
	)
);
eval(cb << get function);

brady_brady_0-1670871142302.png

 

fch_jmp
Level II

Re: Update the content of a DisplayBox with an Associate Array when the selection of a ComboBox changes ?

Hi Brady,

Thanks for your prompt reply.

I took a close look at your script, experimented with it and made some updates to it.

I still have a few questions/remarks if you don't mind:

  • Splitting the main AA into several AAs, one for each option is OK for me
  • Could your script be adapted in order for the window to be Modal ?
    I would prefer to freeze the window interface and immediately close it once the user clicks "Ok".
  • Can a working "recall" Button Box be easily added to this interface ?
  • Lastly, I added some comment to your updated script to explain what I am trying to do.

Thanks again for your help.

Cheers,

François

Re: Update the content of a DisplayBox with an Associate Array when the selection of a ComboBox changes ?

You can make the dialog modal, as below.

 

To make a recall function, you will need to prevent re-initializing the AAs each time the window is opened, by initializing the AAs in another part of the code, that can be separated from the code used to show the window.

 

Each time the OK button is pressed, in addition to saving the new values to the appropriate AA as is already done, you can save the settings off to global (or, preferably, scoped) variables, and use these variables' values to populate the dialog the next time "recall" is pressed.

 

Names Default To Here( 1 );

AAopt1 = Associative Array( Words( "p1,p2,p3", "," ), {1, 2, 3} );
AAopt2 = Associative Array( Words( "p1,p4", "," ), {1, 10} );
AAopt3 = Associative Array( Words( "p2,p5,p6,p7", "," ), {2, 6, 12, 20} );
MainAA = Associative Array( Words( "option1,option2,option3", "," ), Eval List( {AAopt1, AAopt2, AAopt3} ) );


nw = New Window( "xx", <<modal, << on open(eval(cb << get function) ),
	V List Box(
		cb = Combo Box(
			mainAA << get keys,
			Try( TB << delete );
			tableVLB << append(
				tb = Table Box(
					TbSCB = String Col Box( "parameter", mainAA[cb << get selected] << Get Keys ),
					TbNCEB = Number Col Edit Box( "value", mainAA[cb << get selected] << Get Values )
				)
			);
		),
		tableVLB = V List Box(),
		buttonbox("OK", 
			mainAA[cb << get selected] = Associative Array( TbSCB << get, TbNCEB << get );
			Show( mainAA );
		)
	)
);

Re: Update the content of a DisplayBox with an Associate Array when the selection of a ComboBox changes ?

Associative areas have no order. You cannot impose one. JMP orders the results only as a convenience when you examine the contents with a message such as << Get Keys.

 

Names Default to Here( 1 );

// load an associative array in order of C, B, A
aa = Associative Array();
aa["Choice_C"] = ["param 1" => 3, "param 4" => ., "param 6" => 23, "param 7" => 123];
aa["Choice_B"] = ["param 1" => 2, "param 3" => 10, "param 4" => .];
aa["Choice_A"] = ["param_1" => 2, "param 2" => 15, "param_4" => .];

// examine associative array as a whole (JMP orders output, not content, alphanumerically)
Show(
	aa << Get Keys,
	aa << Get Values,
	aa
);

// examine associative array one entry at a time
i = aa << First;
While( Not( Is Empty( i ) ),
	Show( aa[i] );
	i = aa << Next( i );
);