3
$\begingroup$

I was trying to use DynamicModule to create a Input cell that contains a variable assignment, where the variable name is given by a InputField. A minimal example is:

createExample[] := DynamicModule[{name = Null},
  Column[{
    InputField[Dynamic[name]],
    Button["OK",
     With[{name1 = name},
      CellPrint[ExpressionCell[
        Defer[name1 = 99999]
        , "Input"]]]
     ]
    }]
  ]

Running createExample[] will give

1

Enter a variable name called var1 and click OK button 2

However, when I evaluate this assignment, the InputField also changes 3

My question is, how to avoid the change of the variable inside the DynamicModule.

$\endgroup$

3 Answers 3

5
$\begingroup$

If you work with Boxes you don't have to worry about evaluations:

createExample[] := DynamicModule[{name=""},
    Column[{
        InputField[Dynamic[name],Boxes, ContinuousAction->True],
        Button[
            "OK",
            Dynamic @ CellPrint[Cell[BoxData[RowBox[{name, "=", "99999"}]], "Input"]]
        ]
    }]
]

A short animation:

enter image description here

$\endgroup$
1
  • $\begingroup$ Wow thanks! this is exactly what I want. But I'm still curious how could global variable get into the DynamicModule in my version or if there is any caveat of using DynamicModule. $\endgroup$
    – Louis Yu
    May 20, 2019 at 18:06
5
$\begingroup$

Here's a different way to inject the value of name into the cell:

createExample[] := DynamicModule[{name = Null},
  Column[{
    InputField[Dynamic[name], Hold[Expression]],
    Button["OK", 
     name /. Hold[v_] :> CellPrint[ExpressionCell[Defer[v = 99999], "Input"]]]
    }]
  ]

The reason var1 becomes 99999 in the OP's code is that the displayed content of the InputField is the dynamically updated value of name. When name is set to var1, it displays the value of var1. Initially, it has no value, so we see var1 displayed. But when a value for var1 is set, the value is displayed. The above prevents that by specifying the type of the contents to be a held expression. "Held" means that it won't be evaluated. It also means that the value of name will be Hold[var1] when var1 is entered into the field. To handle this, I opted for the alternative method of injecting the user's input into the Set command in the cell.

$\endgroup$
2
  • $\begingroup$ Thank you for your explanation! $\endgroup$
    – Louis Yu
    May 21, 2019 at 3:06
  • $\begingroup$ @L.Yu You're welcome! $\endgroup$
    – Michael E2
    May 21, 2019 at 3:08
2
$\begingroup$

In your code name1 is not localised within the scope of the DynamicModule. Try your experiments on these two variations.

 createExample2[] := 
 DynamicModule[{name = Null}, 
 Column[{Dynamic@name1, InputField[Dynamic[name]],
 Button["OK", With[{name1 = name}, 
   CellPrint[ExpressionCell[Defer[name1 = 99999], "Input"]]]]}]];

 createExample3[]:=DynamicModule[{name = Null, name1}, 
 Column[{Dynamic@name1, InputField[Dynamic[name]],
 Button["OK", With[{name1 = name}, 
  CellPrint[ExpressionCell[Defer[name1 = 99999], "Input"]]]]}]];    
$\endgroup$
2
  • 1
    $\begingroup$ These two works the same as mine... Did I miss something? $\endgroup$
    – Louis Yu
    May 21, 2019 at 3:05
  • $\begingroup$ Yes, In createExample3 name1 is now not a global variable so you can't alter it outside of DynamicModule. $\endgroup$ May 22, 2019 at 4:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.