1
$\begingroup$

Using Manipulate, I would like the items offered in a 2nd PopupMenu to be driven by a 1st PopupMenu. I can get the dynamic driving of the offered items working, but not the initial value of the 2nd PopupMenu when the driving variable from the 1st PopupMenu changes. I also want it to handle cases where the dependent items list is empty {}.

itemLabels = {"a", "b", "c"};
itemMap = <|"a" -> {1, 2}, "b" -> {3, 4}, "c" -> {}|>;
Manipulate[
 {var1, var2},
 {{var1, itemLabels[[1]]}, PopupMenu[Dynamic[var1], itemLabels] &},
 {{var2,
   Dynamic@If[Length[itemMap[var1]] < 1, None, itemMap[var1][[1]]]
   }, Dynamic@PopupMenu[#, itemMap[var1], #] &}
 ]

On run it seems initially to work, the 1st PopupMenu has "a", then if you choose "b" the 2nd PopupMenu switches to offer {3,4} with 3 selected. However, if you then choose 4 in the 2nd PopupMenu and then switch back to "a", the 2nd PopupMenu is "stuck" on 4. If you click the 2nd PopupMenu it does offer correctly {1,2}, but the initialisation is wrong.

If you perform a fresh run then choose "c" from the 1st PopupMenu (for the empty list {}) it correctly shows None. However, if you then choose any of the other 1st PopupMenu options "a" or "b" then go back to "c" it stays "stuck" on whatever you chose for the 2nd PopupMenu.

The attached image shows a typical sequence. Grateful for help on how to get the initial value of the 2nd Popup correctly dynamically refreshed.

typical coupled popup sequence with incorrect initialisation


Solution adapted from @Bob Hanlon answer, in Manipulate target include:

If[ Length[itemMap[var1]] > 1,
   If[ !MemberQ[itemMap[var1], var2],
      var2 = itemMap[var1][[1]]
   ],
   var2 = None
];
{var1, var2},

... (controls) ....
$\endgroup$

1 Answer 1

1
$\begingroup$
$Version

(* "13.3.1 for Mac OS X ARM (64-bit) (July 24, 2023)" *)

Clear["Global`*"]

itemLabels = {"a", "b", "c"};
itemMap = <|"a" -> {1, 2}, "b" -> {3, 4}, "c" -> {}|>;

Manipulate[
 If[(var1 === "a") && ! MemberQ[{1, 2}, var2], var2 = 1];
 If[(var1 === "b") && ! MemberQ[{3, 4}, var2], var2 = 3];
 If[(var1 === "c"), var2 = None];
 {var1, var2},
 {{var1, itemLabels[[1]]}, PopupMenu[Dynamic[var1], itemLabels] &},
 {{var2, 
   Dynamic@If[Length[itemMap[var1]] < 1, None, itemMap[var1][[1]]]}, 
  Dynamic@PopupMenu[#, itemMap[var1], #] &}]

enter image description here

$\endgroup$
1
  • $\begingroup$ Thx @Bob Hanlon, got me on the right track, was able to automate more with: If[Length[itemMap[var1]] > 1, If[! MemberQ[itemMap[var1], var2], var2 = itemMap[var1][[1]]], var2 = None];. Included at bottom of question post. $\endgroup$ Oct 3, 2023 at 2:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.