Manipulate with explicit updates

While your solution works, I personally find it a bit off, since you are actually trying to have dynamic controls for a variable, who's state you immediately change away from the dynamic value just to use it to trigger an event. In short, you want to have one of two actions associated with the button presses, and could code this explicitly using a custom control, rather then indirectly implementing it in the guise of a dynamic controller with an added added event trigger somewhere else. Here is an example of a custom control implementing the events directly:

  Manipulate[
  val,
  {x, {1, 2, 3}, Setter},
  {{val, 0, "operator"}, 
           Row[{ Button["Call f", val = f[x]], 
                 Button["Call g", val = g[x]]}] &}
  ]

Here I added a new scoped variable since the spec for Manipulate needs to associate a variable with the custom control, even though it's not actually controlling any variable. If you wanted access to the operator that performed the last call, you could associate that variable with it.


Three variations using SetterBar, ButtonBar and Setters:

SetterBar:

Manipulate[op, {x, {1, 2, 3}, SetterBar}, 
 {{op, f[1], "op"}, {"f", "g"},SetterBar[Dynamic@op, {(f[x]) ->"f", (g[x]) ->"g"}] &}, 
    TrackedSymbols -> {op}]

ButtonBar:

 Manipulate[op, {x, {1, 2, 3}, SetterBar}, 
 {{op, f[1], "op"}, {"f", "g"}, ButtonBar[{"f" :> (op = f[x]), "g" :>(op = g[x])}] &}, 
   TrackedSymbols -> {op}]

Two Setters:

 Manipulate[op, {x, {1, 2, 3}, SetterBar},
  Row[{Control[{{op, f[1], "op"}, {}, Setter[Dynamic[op], f[x], "f"] &}],
       Control[{{op, g[1], ""}, {}, Setter[Dynamic[op], g[x], "g"] &}]}], 
  TrackedSymbols -> {op}]

@Mohsen. Here is a cleaned up version of your original Manipulate. The Module wrapper is eliminated by introducing val as an invisible control. This is a common and useful way to introduce addition dynamic variables into a Manipulate expression.

Manipulate[
 If[op != "",
   val = Switch[op,
           "f", f[x],
           "g", g[x]];
   op = ""];
 val,
 {val, ControlType -> None},
 {x, {1, 2, 3}, Setter},
 {op, {"f", "g"}, Setter},
 TrackedSymbols -> {op},
 Initialization :> (op = ""; val = "";)]  

It is also good to initialize op and val so that nothing is displayed until the first click is made on the "op" setter. With these minor changes your original approach is really quite valid.

Tags:

Manipulate