2
$\begingroup$

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.

$\endgroup$

1 Answer 1

1
$\begingroup$

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

$\endgroup$
5
  • $\begingroup$ It has to be Manipulate: see end of question. $\endgroup$
    – orome
    Commented Mar 23, 2015 at 19:23
  • $\begingroup$ @raxacoricofallapatorius ok, see my edit. $\endgroup$
    – Kuba
    Commented Mar 23, 2015 at 20:12
  • 1
    $\begingroup$ @raxacoricofallapatorius p.s. I love your profile comment :) $\endgroup$
    – Kuba
    Commented Mar 24, 2015 at 6:39
  • $\begingroup$ Thanks. I'll test it when I'm back at my desk. $\endgroup$
    – orome
    Commented Mar 24, 2015 at 21:30
  • $\begingroup$ I have a follow up question about incorporating this into my Manipulate. $\endgroup$
    – orome
    Commented Mar 27, 2015 at 16:03

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.