cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Check out the JMP® Marketplace featured Capability Explorer add-in
Choose Language Hide Translation Bar
nikles
Level VI

Is there a way for a button box to "know" its location within a container box?

Hi.  I'm wondering if there's a convenient method for a button box to somehow know where it lies within a lineup box.  My specifics:

 

JMP Pro 16.2.0

macOS Monterey 12.5
 

I have a script that creates a window with a LineUp box.  In each cell, there's a button box that I want to perform a different action, based on which column the button appears in.  For example:

 

Names Default to Here(1);

list = {"cat", "dog", "mouse", "kangaroo", "sloth"};
list2 = {"meow", "bark", "squeak", "hop", "zzz"};

lub = LineUpBox(NCol(2), Spacing(5));
For(i=1, i<=NItems(list), i++,
	tb = TextBox(list[i]);
	bb = ButtonBox(list2[i],
	
		//Insert code for the button to somehow identify which button it is within lub.
		
		Speak(list2[i])
	);
	lub << Append(tb);
	lub << Append(bb);
);

New Window("Test", lub);

If I run the script as is, I get:

 

nikles_0-1660751401847.png

But when I click on any of the buttons, I get the error:

"Subscript Range in access or evaluation of 'list2[ /*###*/i]' , list2[/*###*/I]"

 

I understand this error because there's no way for the button box to recall the value of "i" when executed.  My question: is there a method I could use that would allow the button box to "self-identify" where it lies in the line up box when pressed, and use that value as the list2 index in the button script?

 

I'm currently using JSL Quotes and the Substitute command to create the buttons.  In that case I write the contents of the For loop as a JSL Quote and substitute in the value of i, then Eval(Parse()).  This is clunky though, and I'm wondering if there's a better way, like a "bb << Get Location" or "bb << Count Siblings" command.   These commands don't exist of course, but perhaps there's another technique?

 

Thanks!

2 ACCEPTED SOLUTIONS

Accepted Solutions
jthi
Super User

Re: Is there a way for a button box to "know" its location within a container box?

I don't know of any direct method of getting the location, but you could calculate the "location" or you could insert the knowledge to button with Insert one expression into another using Eval Insert, Eval Expr, Parse, and Substitute . You can also use << get button name to get text of the button; or << prev sib with correct reference to get text in the text box; you could "hide" the text in tooltip of button (or index)... and there are many more options, depending on what you want to do and how you want to do it.

View more...
Names Default To Here(1);

aa = Associative Array(
	{"cat", "dog", "mouse", "kangaroo", "sloth"},
	{"meow", "bark", "squeak", "hop", "zzz"}
);

lub = Lineup Box(N Col(2), Spacing(5));

For Each({{key, value}}, aa,
	tb = Text Box(key);
	bb = Button Box(value, << Set function(function({this},
		speak(aa[((this << prev sib) << get text)]);
		// Speak(this << get button name); // in this case button name would be enough
	)));
	lub << Append(tb);
	lub << Append(bb);	
);

New Window("Test", lub);
-Jarmo

View solution in original post

ErraticAttack
Level VI

Re: Is there a way for a button box to "know" its location within a container box?

As an answer to the OP's original question, the answer is yes and it's rather simple.  Here is an example:

Names Default to Here(1);

list = {"cat", "dog", "mouse", "kangaroo", "sloth"};
list2 = {"meow", "bark", "squeak", "hop", "zzz"};

lub = LineUpBox(NCol(2), Spacing(5));
For(i=1, i<=NItems(list), i++,
	tb = TextBox(list[i]);
	bb = ButtonBox(list2[i], <<Set Function( Function( {box}, // box that was clicked
		{Default Local},
		lub = box << Parent; //box lives within the LUB
		boxes = lub << X Path( "//ButtonBox" ); //returns list of all button boxes within lub, in order
		location = Contains( boxes, box ); //returns index of this box
		Show( location );
		Show( list2[location] )
	) ) );
	lub << Append(tb);
	lub << Append(bb);
);

New Window("Test", lub);
Jordan

View solution in original post

4 REPLIES 4
jthi
Super User

Re: Is there a way for a button box to "know" its location within a container box?

I don't know of any direct method of getting the location, but you could calculate the "location" or you could insert the knowledge to button with Insert one expression into another using Eval Insert, Eval Expr, Parse, and Substitute . You can also use << get button name to get text of the button; or << prev sib with correct reference to get text in the text box; you could "hide" the text in tooltip of button (or index)... and there are many more options, depending on what you want to do and how you want to do it.

View more...
Names Default To Here(1);

aa = Associative Array(
	{"cat", "dog", "mouse", "kangaroo", "sloth"},
	{"meow", "bark", "squeak", "hop", "zzz"}
);

lub = Lineup Box(N Col(2), Spacing(5));

For Each({{key, value}}, aa,
	tb = Text Box(key);
	bb = Button Box(value, << Set function(function({this},
		speak(aa[((this << prev sib) << get text)]);
		// Speak(this << get button name); // in this case button name would be enough
	)));
	lub << Append(tb);
	lub << Append(bb);	
);

New Window("Test", lub);
-Jarmo
nikles
Level VI

Re: Is there a way for a button box to "know" its location within a container box?

Hi Jarmo.  The Eval Insert/Eval Expr/Parse Combo is similar to the JSLQuote/Substitute/Parse Combo that I'm currently using.   But the other solutions you provided were exactly the kind of thing I was looking for.  Thanks!

ErraticAttack
Level VI

Re: Is there a way for a button box to "know" its location within a container box?

As an answer to the OP's original question, the answer is yes and it's rather simple.  Here is an example:

Names Default to Here(1);

list = {"cat", "dog", "mouse", "kangaroo", "sloth"};
list2 = {"meow", "bark", "squeak", "hop", "zzz"};

lub = LineUpBox(NCol(2), Spacing(5));
For(i=1, i<=NItems(list), i++,
	tb = TextBox(list[i]);
	bb = ButtonBox(list2[i], <<Set Function( Function( {box}, // box that was clicked
		{Default Local},
		lub = box << Parent; //box lives within the LUB
		boxes = lub << X Path( "//ButtonBox" ); //returns list of all button boxes within lub, in order
		location = Contains( boxes, box ); //returns index of this box
		Show( location );
		Show( list2[location] )
	) ) );
	lub << Append(tb);
	lub << Append(bb);
);

New Window("Test", lub);
Jordan
nikles
Level VI

Re: Is there a way for a button box to "know" its location within a container box?

Thanks!  This is an even more elegant solution.