The other difference between your two snippets is that you switched WithSubmit and MapToAsyncResult. This changes the semantics: in the first snippet, MapToAsyncResult is run on the submitted value, whereas in the second snippet, it is run on the pre-submit value, ie. every time the user types a letter into one of the inputs.

A call to TransmitView immediately after WithSubmit would indeed be useless, because you can just use subm.View; but if there is a mapping in-between, then the transmitted view is the mapped view, which is different from subm.View.

By on 3/8/2016 6:18 AM ()

Hi Loïc, I've thoroughly tested the following statement:

whereas in the second snippet, it is run on the pre-submit value, ie. every time the user types a letter into one of the inputs.

and it does not seem to react this way. In fact, the forms seem to get sent when the submitter is triggered regardless of the positioning of WithSubmit.

The two following forms results in the Map run on trigger:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
namespace Samples

open WebSharper
open WebSharper.JavaScript
open WebSharper.UI.Next
open WebSharper.UI.Next.Html
open WebSharper.UI.Next.Client
open WebSharper.Forms

[<JavaScript>]
module FormTest =

    let f1 =
        Form.Return id
        <*> Form.Yield ""
        |> Form.Map JS.Alert
        |> Form.WithSubmit
        |> Form.Render (fun s sub ->
            form [ fieldset [ div [ Doc.Input [] s ]
                              Doc.Button "Send" [] sub.Trigger ] ])
    let f2 =
        Form.Return id
        <*> Form.Yield ""
        |> Form.WithSubmit
        |> Form.Map JS.Alert
        |> Form.Render (fun s sub ->
            form [ fieldset [ div [ Doc.Input [] s ]
                              Doc.Button "Send" [] sub.Trigger ] ])
    let Main =
        [ f1; br [] :> Doc; br [] :> Doc; f2 ]
        |> Doc.Concat
        |> Doc.RunById "main"

I've also tried directly with View.SnapshotOn and it exhibits the same behavior, whether a View.Map is piped before or after a snapshot, the function in the Map will only get executed when the snapshot is triggered.

Only if I remove completely WithSubmit will the form get submitted on each changes of the input.

Am I missing something?

By on 3/8/2016 4:16 PM ()

Yes you're right, it won't actually run every time you type because SnapshotOn is smarter than I remembered. However it does run once on startup, which you probably don't want.

By on 3/9/2016 2:32 AM ()

SnapshotOn is smarter than I remembered

Nice!

I noticed that it ran on startup and you are right I don't want that. Thanks for the explanation!

By on 3/9/2016 5:39 AM ()

Just to give more details, I now realise that the point that I was missing was that I had a validation on the Yield. Due to that validation, the Map was not executed even though the WithSubmit was placed after the Map.

The following form will not run the Map on startup:

1
2
3
4
5
6
7
Form.Return id
<*> (Form.Yield "" |> Validation.IsNotEmpty "Cannot be empty.")
|> Form.Map JS.Alert
|> Form.WithSubmit
|> Form.Render (fun s sub ->
  form [ fieldset [ div [ Doc.Input [] s ]
  Doc.Button "Send" [] sub.Trigger ] ])
By on 3/9/2016 2:02 PM ()

Great! thanks for the detailed explanation.

By on 3/8/2016 6:56 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper