MFlow  Create and maintain dynamic Web applications as easy and fast as console applications
Thou shall not write request handlers
 This release: 11/06/2014. (@agocorona) <>< . issues & bugs .  Mflow Source code,     source code of this site

Form generator without page refreshes

This time the form generator does not generate a page refresh each time that a option on the menu is pressed 
. The exception of this rule is when a new widget is added to the page, since in this case it is necessary to store the new version of the form generated  and update the edition with the new version. As a rule, ever that an option on a widget modify the presentation of other widget, it is necessary a page navigation. Unless we want to use push widgets (see Push Samples on the demos).

To see a detailed explanation of how it works follow the the explanations fo the two previous versions of the form generator:

Form generator

Form generator with undo

If you want to force a page navigation inside a autoRefresh widget, add to the option an atribute noAutoRefresh

Also, the generated form present the results in the page with no page refresh, by using witerate and dField

See the previous examples for a detailed explanation of the rest of the code.

The first is done using autoRefresh in the menu. In fact there are two nested auto refreshes. This time chooseWidget has an  autoRefresh :  

chooseWidget= autoRefresh $
       (p $ a ! At.class_ "_noAutoRefresh" ! At.href "/" $ "home/reset" )

And as in the previous version, chooseWidget call getOptions for generating combo boxes and checkboxes. getOptions now also has a autoRefresh:

getOptions pf = autoRefresh $ do

        (op,_) <- (,)<$> getString Nothing <! [("size","8"),("placeholder","option")]

Otherwise, the code of this new version is almost the same than in the previous ond, with the above exceptions and the fact that now a new option has been added to chooseWidget. That is a widget that has a button and show the results.  In the previous versions, the button is added after the edition. now it can be added as part of the edition process, but it is also automatically added at the end of the edition if that has not been done by the user:

The genElem for the new result widget is:

genElem ShowResults = Result <$> do
      xs <- getSessionData `onNothing` return []
      pageFlow "" (allOf (map genElem (xs \\ [ShowResults]))) <|> return []
    `wcallback` (\r -> pageFlow "button" $
      submitButton "submit"
      **> h2 "Result:"
      ++> dField(wraw $ b << show r)
      **> return ())

It gets the identifiers of the widgets of the page (Line 1). Then evaluate the rest of the widgets except itself  (Line 2).

Then it drops out the rendering of these widgets and get only the result, and present it below the submitButton that triggers the form submit in the first place when it is rendered. That is done in the wcallback code. wcallback drops out the rendering generated before him.

Another detail: all the presentations of the genElem elements have a dField prefix:

genElem Intv = Result <$> dField (getInt Nothing)
genElem Stringv= Result <$> dField (getString Nothing)
genElem TextArea= Result <$> dField (getMultilineText "")

That is because now the presentation of the form results and the widget updates and validation mesages is trough AJAX, with no page navigation. dField tell MFlow about which  portions of the page will be refreshed this way.  

witerate tell MFlow that it is necessary to load the required javascript code necessary for the AJAX refreshing. Now generateForm has it:

generateForm title xs=
   input ! At.type_ "hidden" ! name "p0" ! value "()"

   ++> (div ! "p0"
   <<< input ! type_ "hidden" ! name "p0" ! value"()"
   ++> ( template title . pageFlow "" . witerate . pageFlow "" . allOf $ map genElem xs))

These are the two main changes in relation with the previous version.

The result is a more responsive application with no more page refreshing than the ones you may expect in a single page application with heavy javascript programming.  Using the checkboxes option, that is a complex widget,  you can see that there is no page refreshing too. Moreover, the server is not called again when is has not to do it. since the little widget definitions are stored int the browser cache. Due to the cascade of two autoRefresh, the getOption widget modifies only its own when necessary, while the whole menu on the left keep unchanged.

Also, the form generated display the result of the inputs, the validation and the content without changing the whole page. Thus the layout and the text can be as complicated and extensive as we like since there would be no penality for the dimamic changes.

In fact we have created a general application for the creation of active web pages. Since the menu can contain wathever widget we like, including active widgets, links to other dynamically generated pages and so on. 

comments powered by Disqus