In a dynamic interface, I am using a custom replacement for InputField
that tracks two things separately:
- The value of the variable that is input.
- The boxes that comprise the user-entered expression.
This way, the user-entered formatting is kept (e.g., scientific notation), incomplete entry is handled smoothly, and the boxes can be initialized to a given number of digits.
Here is a pared-down version:
holdIF[Dynamic[var_], Dynamic[boxes_]] :=
DynamicModule[{updateFunction},
If[boxes == Null,
boxes = ToBoxes[SetPrecision[var, 5]]];
InputField[Dynamic[boxes, {Temporary, updateFunction}], Boxes],
Initialization :> (SetAttributes[updateFunction, HoldRest];
updateFunction[new_, boxVar_] :=
With[{expr = Quiet@ToExpression@new}, boxes = new;
If[expr =!= $Failed, var = expr]
]
)
]
And here is some test code showing it at work.
testvar = 1.23456789;
testboxes = Null;
holdIF[Dynamic[testvar], Dynamic[testboxes]]
Dynamic[{NumberForm[testvar, \[Infinity]], testboxes}]
However, the value of the variable can be modified elsewhere in the dynamic interface. The idea is that the variable are estimates for parameters in nonlinear model fitting; the user enters values and looks at the result in a dynamically-updating plot, and when a suitable starting-point has been found, the user clicks a Button
to initiate an automatic search for a better fit. I therefore want the values displayed in the InputField
boxes to update based on changes to the variable parameters. What would be really nice is if I could signal that the holdIF function should update its box representation by simply setting the boxes variable to Null.
This works if I wrap the holdIF call in a Dynamic
wrapper, because that then regenerates the DynamicModule
when testboxes changes.
testvar = 1.23456789;
testboxes = Null;
Dynamic[holdIF[Dynamic[testvar], Dynamic[testboxes]]]
Dynamic[{NumberForm[testvar, \[Infinity]], testboxes}]
But it really seems that this shouldn't be necessary. Both var and boxes are Dynamic
in the call, so shouldn't there be a way within the holdIF function to notice that boxes has been set to Null and as a result reinitialize var without having to redraw the InputBox
? Thoughts?