8
$\begingroup$

I want to create a bunch of input fields, four in this case, one for each element of the list "x", but since Dynamic has HoldFirst it is not evaluated. Is there any way to get around this, except for declaring it by hand, or messing with strings, I played a bit with Evaluate , andRelaseHold`, but without success.

DynamicModule[{x = Table[0, {4}]},
 Column[{
   Row[Table[
     InputField[Dynamic[x[[i]]], Number, FieldSize -> Tiny],
     {i, 1, 4}]],
   Norm[x]}
  ]
 ]
$\endgroup$

1 Answer 1

12
$\begingroup$

And easy and often seen way of doing this is using With:

 DynamicModule[{x = Table[i, {i, 4}]},
 Column[{Row[Table[
   With[{i = i}, 
       InputField[Dynamic[x[[i]]], Number, FieldSize -> Tiny]
   ], 
 {i, 1, 4}]], Dynamic@Norm[x]}]]

You could also write it out with i=m and switching symbols if you think i=i looks confusing.

This page in the section "Nesting Dynamic" is a good read about a situation in which this trick is also used. However there it is used to avoid unwanted dynamic updates. Also found in the documentation with interactive examples "tutorial/AdvancedDynamicFunctionality"

Updated with an explanation

I've been giving out this answer a couple of times now, and I think it might be worth adding a little bit of information about what really is the problem in these situations.

The thing is that Dynamic has the attribute HoldFirst

Attributes[Dynamic]

{HoldFirst, Protected, ReadProtected}

This means the first argument given to it is held in place, consider for example what happens when we run a Table over Hold:

 Table[Hold[i],{i,3}]

{Hold[i], Hold[i], Hold[i]}

Because i is held, it doesn't change at each iteration. What we need to do to fix this is to make sure that i is evaluated before it is put into Hold so it ends up holding the value and not the symbol, for example by passing the value into a function

Table[Hold[#] &@i, {i, 3}]

{Hold[1], Hold[2], Hold[3]}

Or as is typically done by using With

Table[With[{i = i}, Hold[i]], {i, 3}]

{Hold[1], Hold[2], Hold[3]}

What happens is that when With[{i=i},code] is evaluated by table, the iterator symbol takes on its value, and we actually have for example for the first iteration With[{i=1},code] so rather then Hold holding i, it gets the value. The same trick is employed to get the value rather then the symbol into the Dynamic.

$\endgroup$
1
  • $\begingroup$ +1 for "if you think i=i looks confusing" $\endgroup$ Aug 28, 2012 at 12:12

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.