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$
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$
  • $\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$ – L.Yu May 20 '19 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$
  • $\begingroup$ Thank you for your explanation! $\endgroup$ – L.Yu May 21 '19 at 3:06
  • $\begingroup$ @L.Yu You're welcome! $\endgroup$ – Michael E2 May 21 '19 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$
  • 1
    $\begingroup$ These two works the same as mine... Did I miss something? $\endgroup$ – L.Yu May 21 '19 at 3:05
  • $\begingroup$ Yes, In createExample3 name1 is now not a global variable so you can't alter it outside of DynamicModule. $\endgroup$ – Emerson Willard May 22 '19 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.