Subscribe Bookmark RSS Feed

List Boxes - the "set selected" property

This query is related to an earlier one of mine concerning upgrading some scripts to make better use of JMP 9's capabilities (http://communities.sas.com/message/109908#109908), but it's not quite the same problem, I think.  Essentially it concerns the redrawing of a window containing a list box from which a selection has already been made.  In the following simplified example, I'm making a selection from List A, then recreating the window in which List A appears with a second list box (List Box B) whose contents depend upon the selection made from A.  If the user selects from the List Box B then the final selection appears in the text box below it.  If a selection is made from List Box A, a new list of choices is supplied in List Box B from which the user still has to make a final selection.  Running this in JMP 8 works as I want it to, whereas running it in JMP 9 creates an infinite loop.  I think I can see why: the line I've marked with a comment (which highlights the selection made from List Box A with a "<< set selected" property when both list boxes A and B appear in the window) treats the assignment as if I'd made that selection by clicking on it, and acts accordingly.  Obviously I could just remove this line, but if I do that, the user can't see the path that led to the final selection from the list boxes - and it's necessary that he should.  Alternatively I could simply include all the list boxes in the window from the beginning and not redraw the window at all, but in the real version of this the user doesn't know at the outset how many list boxes he's going to need to use - and I don't really want to show more on the screen at any one time than are actually needed.

List_A = {"Andy", "Bessie", "Carrie", "Davina", "Eddie"};

List_B = {};

Expr_Redraw_NW = expr(

      

       List_Box_A = List Box(List_A, eval(Expr_Create_List_B));

      

       NW = new window("New Window",

              HListBox(

                     Panel Box("First Choice", List_Box_A),

                     if(A_Choice > 0,

                           Panel Box("Second Choice",

                                  List_Box_B,

                                  Text Box("  "),

                                  TextBox_Answer = Text Box("")

                                  )

                           )

                     )

              );

       if(A_Choice > 0, List_Box_A << set selected(A_Choice)); // This line causes the problem;

       NW << move window(200, 200);

       );

Expr_Create_List_B = expr(

       Prefix = (List_Box_A << get selected)[1];

       show(Prefix);

       A_Choice = (List_Box_A << get selected indices)[1];

       show(A_Choice);

      

       List_B = {};

       for(i=1, i<=5, i++,

              insert into(List_B, Prefix || " " || char(i))

              );

      

       List_Box_B = List Box(List_B,

              B_Choice = (List_Box_B << get selected)[1];

              TextBox_Answer << set text("Selection is: " || B_Choice);

              NW << reshow

              );

      

       NW << close window;

       eval(Expr_Redraw_NW);

       );

List_Box_B = List Box(List_B, print(""));

TextBox_Answer = Text Box("");

Answer = "";

A_Choice = 0;

eval(Expr_Redraw_NW);

Can anyone see a simple way out of this that doesn't involve substantially restructuring the way it works?  I've got a similar problem in three or four scripts, so I'd like to keep any remedial work to a minimum if I can.

Many thanks for any help received.

1 ACCEPTED SOLUTION

Accepted Solutions
Solution

I have not found a super-simple solution. One way to eliminate the risk of  falling into the recursive trap is have a one-way communication between the key expressions.

Below is an example that conditionally deletes/appends the Panel Box that contains List_Box_B, instead of redrawing the entire window. Thus List Box A does not need to be updated, and all the redrawing work is called from the script in List_Box_A without "feedback" from Expr_Create_List_B. It may not as simple as you'd hoped but it seems to work in JMP9.

List_A = {"Andy", "Bessie", "Carrie", "Davina", "Eddie"};

List_B = {};

Expr_Redraw_NW = Expr(

     

          List_Box_A = List Box(

                    List_A,

                    Eval( Expr_Create_List_B );

                    Try( Panel_Box_B << delete );

                    If( A_Choice > 0,

                              HL << Append( Eval( Expr_Panel_Box_B ) );

                              A_Choice = 0; // to enable reset by control-clicking selection

                    );

          );

     

          If( A_Choice == 0,

                    NW = New Window( "New Window",

                              HL = H List Box(

                                        Panel Box( "First Choice", List_Box_A ),

                                        If( A_Choice > 0,

                                                  Eval( Expr_Panel_Box_B )

                                        )

                              )

                    )

          );

          NW << move window(200, 200);

);

Expr_Create_List_B = Expr(

  Try(

                    Prefix = (List_Box_A << get selected)[1];

                    Show( Prefix );

                    A_Choice = (List_Box_A << get selected indices)[1];

                    Show( A_Choice );

     

                    List_B = {};

                    For( i = 1, i <= 5, i++,

                              Insert Into( List_B, Prefix || " " || Char( i ) )

                    );

     

                    List_Box_B = List Box(

                              List_B,

                              B_Choice = (List_Box_B << get selected)[1];

                              TextBox_Answer << set text( "Selection is: " || B_Choice );

              NW << reshow

                    );

          );

);

Expr_Panel_Box_B = Expr(

          Panel_Box_B = Panel Box( "Second Choice",

                    List_Box_B,

  Text Box( "  " ),

                    TextBox_Answer = Text Box( "" )

          )

);

List_Box_B = List Box( List_B, Print( "" ) );

TextBox_Answer = Text Box( "" );

Answer = "";

A_Choice = 0;

Eval( Expr_Redraw_NW );

2 REPLIES
Solution

I have not found a super-simple solution. One way to eliminate the risk of  falling into the recursive trap is have a one-way communication between the key expressions.

Below is an example that conditionally deletes/appends the Panel Box that contains List_Box_B, instead of redrawing the entire window. Thus List Box A does not need to be updated, and all the redrawing work is called from the script in List_Box_A without "feedback" from Expr_Create_List_B. It may not as simple as you'd hoped but it seems to work in JMP9.

List_A = {"Andy", "Bessie", "Carrie", "Davina", "Eddie"};

List_B = {};

Expr_Redraw_NW = Expr(

     

          List_Box_A = List Box(

                    List_A,

                    Eval( Expr_Create_List_B );

                    Try( Panel_Box_B << delete );

                    If( A_Choice > 0,

                              HL << Append( Eval( Expr_Panel_Box_B ) );

                              A_Choice = 0; // to enable reset by control-clicking selection

                    );

          );

     

          If( A_Choice == 0,

                    NW = New Window( "New Window",

                              HL = H List Box(

                                        Panel Box( "First Choice", List_Box_A ),

                                        If( A_Choice > 0,

                                                  Eval( Expr_Panel_Box_B )

                                        )

                              )

                    )

          );

          NW << move window(200, 200);

);

Expr_Create_List_B = Expr(

  Try(

                    Prefix = (List_Box_A << get selected)[1];

                    Show( Prefix );

                    A_Choice = (List_Box_A << get selected indices)[1];

                    Show( A_Choice );

     

                    List_B = {};

                    For( i = 1, i <= 5, i++,

                              Insert Into( List_B, Prefix || " " || Char( i ) )

                    );

     

                    List_Box_B = List Box(

                              List_B,

                              B_Choice = (List_Box_B << get selected)[1];

                              TextBox_Answer << set text( "Selection is: " || B_Choice );

              NW << reshow

                    );

          );

);

Expr_Panel_Box_B = Expr(

          Panel_Box_B = Panel Box( "Second Choice",

                    List_Box_B,

  Text Box( "  " ),

                    TextBox_Answer = Text Box( "" )

          )

);

List_Box_B = List Box( List_B, Print( "" ) );

TextBox_Answer = Text Box( "" );

Answer = "";

A_Choice = 0;

Eval( Expr_Redraw_NW );

Ingenious!  Yes - it solves the problem very nicely, and not only that, it also suggests a way I could extend the process to cover a chain of such queries.  Many thanks!

David