Message Boards Message Boards

GROUPS:

How can I create interactive popup menus in Manipulate

Posted 3 years ago
4404 Views
|
4 Replies
|
2 Total Likes
|

Hello everyone,

I have a list that I want to make into a popup menu control in a Manipulate. It is roughly

{A1,A2,A3,…,B1,B2,…}

The problem is, that with 24,000 items, the list is too long and Manipulate slows to a crawl every time I open the menu to make a choice. So I broke the list into sublists of the As, Bs, Cs, and so on, and created a popup menu with the short list of sublist names

{A,B,…}

and a second popup menu whose items are the items from the sublist selected in the first menu. In other words, the items displayed in the second menu depend on what is selected in the first. This works except that whenever I choose a new item from the first menu (e.g., H), I cannot get the second menu to display the first item of the new sublist (i.e., H1) by default. The second menu displays nothing, and I have to open it and select the first item.

How can I get the second menu to display the first item by default? Any tips would be much appreciated.

Gregory

4 Replies

Hi Gregory Lypny!

One way to do this would be to change the value of both the letter and the number from the first menu. Let the first menu set the value of {letter,number} to {"A",1},{"B",1} and so on. You can define labels to each of the choices so it still shows up as "A","B" etc.

letterList = {"A", "B", "C", "D", "E", "F"};
numberList = Range[1, 10];
letterLabels = 
 Table[{letterList[[i]], numberList[[1]]} -> letterList[[i]], {i, 
   Length[letterList]}];
letter = letterList[[1]];
number = numberList[[1]];

letterLabels is what you put in the first menu, it now has the value:

{{"A", 1} -> "A", {"B", 1} -> "B", {"C", 1} -> "C", {"D", 1} -> 
  "D", {"E", 1} -> "E", {"F", 1} -> "F"}

This causes a problem in that when the value of {letter, number} is something like {"A",2} rather then {"A",1}, there will not exist a label to go with the value combination so the menu will display blank. This is solved using default labels, set this to be the dynamically updated value of "letter":

PopupMenu[{Dynamic[letter], Dynamic[number]}, letterLabels, 
 Dynamic[letter]]
PopupMenu[Dynamic[number], numberList]

Code attached, hope it helps!

Patrik

Attachments:

Hi Patrick,

Thanks for the suggestion. I'm going to give it a try. I think a limitation of Manipulate is that the default start values for the controls are a little cumbersome to program.

Gregory

Hi,

It is entirely possible to do that in manipulate. You can define a function that should be used for controlling a manipulate variable:

{{u,uinit,ulbl},func} - create an arbitrary control from a function

Manipulate[
 Symbol[letter <> ToString[number]], 
 {{letter, letterList[[1]],  "Letter: "}, PopupMenu[{#, Dynamic[number]}, letterLabels, #] &}, 
 {{number, numberList[[1]], "Number: "}, PopupMenu[#, numberList] &}]

manipulatedropdown

These are just same expressions as above but instead designed as pure functions.

Notebook attached!

Hope it helps

Attachments:

A pure function as the argument to Popup menu. Never would have thought of that. Thanks!

Gregory

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract