The new primitive, push, like autoRefresh, is a modifier of a widget behavior. In this case push will execute the widget and present the output again and again using ajax internally. This is an example:
The image is not very exciting. I will try to add another better. In this example the push widget is above the text box.
The code is as follows:
pushSample= do tv ← liftIO $ newTVarIO $ Just "The content will be appended here" page $ h2 << "Push example" ++> p << "The content of the text box will be appended to the push widget below." ++> p << "A push widget can have links and form fields." ++> p << "Since they are asynchronous the communucation must be trough..." ++> p << "The input box is configured with autoRefresh" ++> hr ++> pageFlow "push" (push Append (disp tv) <** input tv) **> br ++> br ++> wlink () << b << "exit" where -- the widget being pushed: disp tv= do setTimeouts 100 0 line ← tget tv liftIO $ when (line ≡ "kill") $ myThreadId ↠ killThread p << line ++> noWidget -- The input box input tv= autoRefresh $ do line ← getString Nothing <** submitButton "Enter" tput tv line tput tv x = atomic $ writeTVar tv ( Just x) tget tv= atomic $ do mr ← readTVar tv case mr of Nothing → retry Just r → do writeTVar tv Nothing return r atomic= liftIO . atomicallyThere are still some minor issues with this widget, but I expect to fix them soon. As you can see, the push widget retry when Nothing is available in the TVar. When the input widget tput's something in the variable, it is read, emptied and returned to be displayed. The other widgets of the page must be configured with autorefresh, unless we want to navigate away from the page. This is why the text input box and the button are under autoRefresh, but the exit link is not.