# Asynchronous evaluation on EventHandler

How can I make this progress bar appears when I press Enter? The Button Evaluate works just fine, but when Enter is pressed it jumps the progress bar.

It would be easy if EventHandler could have Method-> "Queued", but is't not the case.

Here is my code:

DynamicModule[{output="",slowReport,progress,str,btnEval,enterAction,number,enterEval},

progress=ProgressIndicator[Dynamic[Clock[Infinity]],Indeterminate,ImageSize->280];

enterEval=EventHandler[#,{"ReturnKeyDown":>(output=progress;output=slowReport[])}]&;
btnEval=Button["Evaluate",(output=progress;output=slowReport[]),Method->"Queued"];

Dynamic@Panel@Column[{Row[{InputField[Dynamic[number], String]//enterEval,btnEval}]," ",output," "},Alignment->Center]

,Initialization:>
(
SetOptions[$FrontEndSession,DynamicEvaluationTimeout->10]; slowReport[]:=(Pause[1];ToExpression@number^2) ) ]  Here is what happens when Evaluate is pressed: - Maybe you can play with CellEventActions. – Kuba Dec 1 '13 at 14:13 There are some ideas here you might be able to use: Asynchronous evaluation: Is it possible? – Michael E2 Dec 1 '13 at 20:11 As an FYI SetDelayed doesn't work within the body of a DynamicModule. You need to use Initialization. – Mike Honeychurch Dec 2 '13 at 1:10 @MikeHoneychurch, changed into Initialization. Tks. – Murta Dec 2 '13 at 23:08 ## 3 Answers Version 10.1 now supports the Method->"Queued" option for EventHandler. Unfortunately, I forgot to document that fact (sorry!). Documentation updated now for future releases. Also, your code could be improved by making a progress indicator that doesn't do kernel evaluations. This progress indicator just runs in the FE and won't get any hiccups from trying to interrupt the kernel to get processing time: ProgressIndicator[Appearance -> "Indeterminate", ImageSize -> 280]  - tks for sharing this John. – Murta Apr 23 '15 at 22:26 Should I do just this: EventHandler[#,{"ReturnKeyDown":>(output=progress;output=slowReport[])},Method-‌​>"Queued"], it's not working for me. Any clue? – Murta Apr 28 '15 at 19:39 @Murta right, if it would have worked, this should too DynamicModule[{x = ""}, EventHandler[ InputField[Dynamic[x], String], {"ReturnKeyDown" :> (x = "124"; SelectionMove[EvaluationNotebook[], After, Expression])}, Method -> "Queued" ] ] and it isnt :/ – Kuba May 22 '15 at 7:24 Here is yet another funny way to do things. What is needed is a queued submit function like ParallelSubmit. One key below is using DynamicWrapper to hide an asynchronous updating of output. Another key is "touching" number (à la Unix) when the button or enter/return is pressed. These don't change the value of number, so to trigger an update, touch changes the value and immediately changes it back. I moved Dynamic from wrapping Panel to output. This eliminated each update leading to two calculations of slowReport. DynamicModule[{output = "", slowReport, progress, str, btnEval, enterAction, number, enterEval, touch}, progress = ProgressIndicator[Dynamic[Clock[Infinity]], Indeterminate, ImageSize -> 280]; slowReport[n_] /; NumericQ[ToExpression[n]] := (Pause[1]; ToExpression@n^2); slowReport[_] := (Pause[1]; ""); touch = Function[n, (n = ""; n = #) &@n, HoldAll]; enterEval = EventHandler[#, {"ReturnKeyDown" :> (output = progress; touch[number])}] &; btnEval = Button["Evaluate", (output = progress; touch[number]), Method -> "Queued"]; output = progress; (*Dynamic@*) Panel@Column[ {Row[{InputField[Dynamic[number, (output = progress; number = #) &], String] //enterEval, btnEval}], DynamicWrapper[" ", output = slowReport[number], TrackedSymbols :> {number}, SynchronousUpdating -> False], Dynamic @ output, " "}, Alignment -> Center], Initialization :> (SetOptions[$FrontEndSession, DynamicEvaluationTimeout -> 10])]


By the way, perhaps one might to be able to use ParallelSubmit to achieve the goal.

-
The second time you press return (without changing input) the progress indicator stays on forever. – Sjoerd C. de Vries Dec 1 '13 at 17:03
@SjoerdC.deVries Thanks. Fixed, I think, although in yet another roundabout way. – Michael E2 Dec 1 '13 at 17:26
Oh my God, why life has always to be so complicated inside DynamicModule! @MikeHoneychurch, It's this kind of thing that I complain here in #1. – Murta Dec 1 '13 at 17:33
@Murta I know, I know. I keep hoping someone will show the "easy" way that eludes me. Sometimes they're like objects that find out things by rumor instead of direct object-oriented messaging. – Michael E2 Dec 1 '13 at 17:40
@Murta while life can sometimes be complicated in DynamicModule I don't think that is where the "blame" lies. You are hoping to be able to witness the result of multiple actions from one single EventHandler event. My reading of the docs is that this is not possible. I think it is ok to be frustrated with a perceived lack of functionality that may or may not be available within DynamicModules but if you try to do something outside what is documented then I don't think there is cause to complain. – Mike Honeychurch Dec 1 '13 at 22:12

If you want to send queued sequence of procedures to the kernel with controller which has not got this Method you can mimic this with ScheduledTasks.

Notice that this way is useful only for non continuous events like clicks, etc. Because separate scheduled tasks are independent and there is no guarantee of queue.

But for your example it fits quite well:

DynamicModule[{
output = "",
slowReport,
progress,
number,
enterEval},
progress = ProgressIndicator[Appearance -> "Necklace"];

enterEval =
EventHandler[#, {"ReturnKeyDown" :>
output = slowReport[], {.01}]}] &;

Column[{
InputField[Dynamic[number], String] // enterEval,
Dynamic[output, TrackedSymbols :> {output}]
}],

Initialization :> (
slowReport[] := (   Pause[3]; ToExpression@number^2);

)]


p.s. do not ask me why there is TrackedSymbols... It just won't work without it.

-