cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Try the Materials Informatics Toolkit, which is designed to easily handle SMILES data. This and other helpful add-ins are available in the JMP® Marketplace
Choose Language Hide Translation Bar
miguello
Level VI

List of tables: how to interactively update and not loose the selection

I have seen discussion on this topic, and I couldn't find the solution.

The problem is the following:

 

I'm orking with the list of tables that is displayed in a List Box. I use N Table() way of getting a list of names for all the tables.

What I want is that if I click to select any lines in that list - the list itself updated and checked if there are new opened tables or some tables were closed.

Good wat to do that is to use Set Items(openDTs) each time I click to select. It updates the list of tables just fine - the problem is it drops the selection.

If I use Append(openDTs) on the List Box - it adds whatever new tables were opened, but if I close the table, it does not delete the closed table.

 

What is the most elegant and correct way of having the list of the tables being updated, reflecting opened and closed tables upon any click on the list, so that selection is kept?

4 REPLIES 4
miguello
Level VI

Re: List of tables: how to interactively update and not loose the selection

For now I solved it this way:

 

I remember the name of the selected table, then I use Set Items to completely rewrite, then I iterate through the whole list and compare remembered name with the new list (order, therefore indeces might be different now!). As soon as I hit the same name, I remember that index and set seceted using this index.

 

Here is the code:

listofTablesSelect=Function({this},{selectedIndex},
	// This function is called when the List Box selection changes
	
	selectedIndex = this << Get Selected;
	selectedTableName = selectedIndex[1];
	refreshListofTables();
	for (i=1, i<=N Items(listofTablesList = this<<Get Items), i++, 
		if(listofTablesList[i] == selectedTableName, recallIndex = i);	
	);
	this << Set Selected(recallIndex);

Where refreshListofTables uses Set Items:

refreshListofTables = Function({}, 
Show("Trying to refresh list of tables");
openDTs = List();
For( i = 1, i <= N Table(), i++,
	Insert Into( openDTs, Data Table( i )<<Get Name() );
	);
return(openDTs);
listofTables<<Set Items (openDTs);
);

The only thing that I don't like: Log Window is displaying "JSL recursion prevented" - where exactly is the recusrion? Is 

this << Set Selected(recallIndex);

effectively calling the whole 

refreshListofTables

 again, therefore going into resursion?

Any way around it?

 

Thakns, 

M

gzmorgan0
Super User (Alumni)

Re: List of tables: how to interactively update and not loose the selection

 miguello,

 

If you are using JMP 14, there is a new command Get Data Table List() that returns a list of opened data tables. If you are not using JMP 14 then the N Table() command is required.

 

Also Subscribe to Data Table List(<subscriber>, OnOpen() | OnClose() | OnRename() ) is available on JMP 12, 13,14.  

 

Below is a script to explore table subscriptions. Note instead of show ctbls, you could update the list on each change.

 

Final note, NTable() will "count" invisible data tables, but Private data tables are not counted.

 

 

Names Default To Here( 1 );

//---Use one of these functions
//---- JMP 14 function
//ctbls = Get Window List( Type("DataTables")) << Get Window Title();

// --- User function to returns a list of table names   
curtbl_fn = Function({}, {nt, tlist={}, i},
  nt= NTable();
  If(nt >0,
	For(i=1, i<=nt, i++,
		Insert into(tlist, Data Table(i) << get name) 
	);
  ); // end if
  tlist
); //end Function


//------ functions to handle when a new table is created, whe a table is renamed and when a table is closed.

fnew = Function( {dtab},
	Insert Into(ctbls, dtab << Get Name );
	show(ctbls, NTable())
);
fnnme = Function( {dtab, b},{i},
     show(dtab, b);
     i = contains(ctbls, b  );
	 If (i>0, ctbls[i] = dtab << get name);
	 show(ctbls, NTable())
);
fclose = Function( {dtab}, {i},
     i = contains(ctbls, dtab<<get name );
     show(dtab, i);
     If (i>0, remove from(ctbls, i));
     show(ctbls, NTable());
 );

Open("$Sample_Data/Variability Data/2 Factors Crossed.jmp");
Open("$Sample_Data/Baseball.jmp");
Open("$Sample_Data/Basketball.jmp");
Open("$Sample_Data/Football.jmp");
Open("$Sample_Data/Fishing.jmp");
Open("$Sample_Data/Pogo Jumps.jmp");

//_____________________________________________________________________
//--- Run to here ------------------------

//use the JMP 14 command or the functions
ctbls =curtbl_fn();
show(ctbls, NTable());
//--- Run to here and check the log------------------------

aSub = Subscribe to Data Table List( , OnOpen( fnew ) );
Subscribe to Data Table List( aSub,    OnRename( fnnme ) );
Subscribe to Data Table List( aSub,    OnClose( fclose ) );


dt = Open( "$SAMPLE_DATA/Iris.jmp" );
Wait( 2 );
dt << setname( "yyy" );
// two printouts: one  for OnOpen() and one for OnRename()

//--- Run to here and check the log------------------------

Close(Data Table("Fishing"), NoSave);
//--- Run to here and check the log------------------------

//Check Table manipulations
Data Table("yyy") << Subset (All Rows, All Columns, Output Table Name ("Iris redux") );
//--- Run to here and check the log------------------------


Unsubscribe to Data Table List(asub, All);

print("should not do anything");
Close(Data Table("Baseball"), NoSave);

 

miguello
Level VI

Re: List of tables: how to interactively update and not loose the selection

Thanks, Georgia!

 

This is definitely a more elegant way of having up-to-date list of tables. The only small question is - what is the best way to update the List Box with an item selected without loosing the selection?

gzmorgan0
Super User (Alumni)

Re: List of tables: how to interactively update and not loose the selection

miguello,

 

Kevin Anderson posted a script from the 2nd edition of our book, JSL Companion in the discusson at this link

Compare lists but with partial strings

 

So, my recommendation is to modify your first function that returns a list of selected items in the list box. Then use the Lfunc() function with contains or use an intersection function that finds an intersection of the selected list with the ctbls, the list of current tables. The resulting list will be the ones you need to select. The link describes a simple technique using associative arrays to find an intersection, or look at the attached script from chapter 5: function uniq_intersect(ctbls, sellist) .

 

I hope that is clear. I did not add more yesterday, since your other function was so close.