2

I have a string with a variable length, determined by the value of a SetterBar and whose characters are determined by a corresponding number of PopupMenu controls, so that when the SetterBar value is "+" I get

and when it is "-" I get

and, or course, with the string changing dynamically as the PopupMenu controls values are changed. But I can't get either the dynamic update of the number of PopupMenus or the dynamic update of the string to work with

Manipulate[
 With[{mk, n},
  n = If[ r4 == "+", 4, 3];
  StringJoin[mk[#] & /@ Range[n]]],
  Row[PopupMenu[Dynamic[mk[#]], CharacterRange["A", "Z"], ImageSize -> {45, 20}] & /@ Range[n]],
  {{r4, "-", "R4"}, {"+", "-"}, ControlType -> SetterBar, Appearance -> "Palette"}]

Ideally, also, each of the PopupMenus should be "A" by default, and the string "AAAA".

This seems like it should be simpler than I'm making it; but I think I'm doing multiple things wrong all at once.

How do I dynamically construct a string from a variable number of PopupMenus in Manipulate?


FWIW, this is intended to recreate the behavior of something like

Manipulate[ 
 With[{spec = StringJoin[Table["A", {If[r4 == "-", 3, 4] - StringLength[start]}]] <> start},
  spec],
  {{start, "", "Start"}, InputField[Dynamic[start], String] &},
  {{r4, "-", "R4"}, {"+", "-"}, ControlType -> SetterBar, Appearance -> "Palette"}]

in environments (like Demonstrations) where InputField is prohibited.

orome
  • 12,819
  • 3
  • 52
  • 100

1 Answers1

1

Manipulate version.

Manipulate[
 Row@string
 ,
 Column[{Dynamic[pop /@ Range[n] // Row, TrackedSymbols :> {n}], 
   SetterBar[
    Dynamic[x, 
     If[# === "+", n++; string = Join[string, {"a"}], n--; 
       string = Most@string] &], {"+", "-"}]}]
 ,

{x, None}, {n, None}, {string, None} , Initialization :> ( pop[i_] := With[{j = i}, PopupMenu[Dynamic[string[[j]]], CharacterRange["a", "z"]]]; string = ConstantArray["a", 4]; n = 4;

) ]

enter image description here

DynamicModule version.

Let me not use Manipulate, it is more handy with DynamicModule in more complex cases:

DynamicModule[{ pop, x, n = 4, string = ConstantArray["a", 4] },

pop[i_] := With[{j = i}, PopupMenu[Dynamic[string[[j]]], CharacterRange["a", "z"]] ];

Panel@Column[{ Dynamic[pop /@ Range[n] // Row, TrackedSymbols :> {n}], SetterBar[ Dynamic[x, If[# === "+", n++; string = Join[string, {"a"}], n--; string = Most@string ] &], {"+", "-"}], Dynamic@Row@string } ] ]

enter image description here

Kuba
  • 136,707
  • 13
  • 279
  • 740