# How can I create a custom control which evaluates to a list of values or replacements?

I have a set of variables which are used in various places in my calculations (solving a system, initial conditions, etc.). In order to make this easier to deal with, I want to make a control-like thing which makes them easier to manipulate, rather than just using long lists of unlabeled values such as

````calculateValues[{0, 0, π, 0.5, 3}]
````

So far I have something like this:

This clearly doesn't work, and I expect in order to get it working properly I'll need to use `Interpretation` or more `Dynamic` incantations, but I can't figure out exactly what needs to happen. Any advice would be appreciated. Thanks in advance!

-

## 3 Answers

You could do

````myControl[varNames_List, start_: 0] := 
 myControl[varNames, ConstantArray[start, Length@varNames]]

myControl[varNames_List, start_List] := 
 Interpretation[{vars = start}, 
  Panel[Grid[{varNames, 
     Array[InputField[Dynamic@vars[[#]], 
        FieldSize -> {{0, Infinity}, 1}] &, Length@vars]}]], vars]
````

Now you can run that function to create a control `myControl["a"~CharacterRange~"g"]`. Each instance will have its own values and they all evaluate to their values when supplied as input

-
This works great, thanks! But what is the purpose of the `DynamicSetting` and `Evaluate`? It seems that if I remove them, it works just the same way. Also, I would expect to need `Dynamic[vars]` instead of `vars` at the end... – jtbandes Nov 23 '12 at 20:10
@jtbandes, without the `DynamicSetting` it shouldn't work as I thought you wanted. Try running `myControl["a"~CharacterRange~"g"]` and then adding `+3` to the output in the output cell with and without the `DynamicSetting` – Rojo Nov 23 '12 at 21:14
The `Evaluate` is probably useless, but since `Interpretation` has attribute `HoldAll` and I don't know why it's not simply `HoldRest`, I wanted to make sure it evaluated the first argument. However, it seems to evaluate it anyway – Rojo Nov 23 '12 at 21:21
The second argument of `Interpretation` needs to be what you want the kernel to receive when you use that control as input. You want the values of `vars`, and not a visual GUI that shows the dynamically updated value of `vars`. Always remember that `Dynamic` is only for SHOWING updated output (or in a control such as `Slider[Dynamic@..]` "as a notation" for input in controls). – Rojo Nov 23 '12 at 21:25

1
@jtbandes, I just passed through the docs of `Interpretation` and saw that it can take an extra argument, specifying the local variables, and using it expands to the same code that I had used before: DynamicSetting@DynamicModule[..., but is way neater. Edited – Rojo Nov 25 '12 at 5:17
show 1 more comment

You could use interpretation.

Here's the idea.

````SetAttributes[makeDynamicPanel, HoldFirst]
makeDynamicPanel[x_, defaultValue_] :=
 Module[{y},
    y = 
       Interpretation[
          Panel@InputField[Dynamic[x]]
          ,
          x
       ];
    x = defaultValue;
    y
 ]
````

Then you do for example

````makeDynamicPanel[z, {0, 0, π, 0.5, 3}]
````

and you get a panel that allows to edit the value of z and can be used as argument to your function, you can even do for example panel + 2 and get a valid value, it's quite practical.

-

I would suggest using another list (`vals`) to store values for the variables `vars`. To set up a list of controllers (`InputField`s here) programmatically, some clever construct is required. Here I used an explicit `Function` call to save the changed value of the $i^{th}$ element of vals inside the `Dynamic` (as the `#` stands for the index of the list element, not the actual controller value, which is denoted as `$x`), but this can also be achieved using `With`.

````calculateValues[v_List] := Plus @@ (v^Range@Length@v);

vars = {a, b, c, d, e};
vals = {1, 2, 3, 4, 5};

Panel[
 Grid[{
   Text /@ vars,
   InputField[Dynamic[vals[[#]], Function[{$x}, vals[[#]] = $x]], 
      FieldSize -> {{0, Infinity}, 1}] & /@ Range@Length@vals
   }]]
````

````Dynamic@vals
````
````{1, 2, 3, 4, 5}
````
````calculateValues@vars
````
````a + b^2 + c^3 + d^4 + e^5
````
````Dynamic[calculateValues@vars /. Thread[vars -> vals]]
````
````3413
````
-
lang-mma
{"extraction_info": {"found_math": true, "script_math_tex": 0, "script_math_asciimath": 0, "math_annotations": 0, "math_alttext": 0, "mathml": 0, "mathjax_tag": 0, "mathjax_inline_tex": 1, "mathjax_display_tex": 0, "mathjax_asciimath": 0, "img_math": 0, "codecogs_latex": 0, "wp_latex": 0, "mimetex.cgi": 0, "/images/math/codecogs": 0, "mathtex.cgi": 0}, "config": {"markdown_headings": true, "markdown_code": true, "boilerplate_config": {"ratio_threshold": 0.18, "absolute_threshold": 10, "end_threshold": 15, "enable": true}, "remove_buttons": true, "remove_image_figures": true, "remove_link_clusters": true, "table_config": {"min_rows": 2, "min_cols": 3, "format": "plain"}, "remove_chinese": true, "remove_edit_buttons": true, "extract_latex": true}, "english_confidence": 0.8708423376083374, "perplexity_flag": "middle"}