I'm still not very well-versed in Piglets but I'm not sure this can be solved nicely. Basically the problem here is that you want to put validation on a field that depends on a previous one, but on the field you want to access the previous one you only have access to the value of that particular one. If you decide to instead do the validation on the whole Piglet where you have both values you can obviously do it but when you pass on the reader you will receive all errors from that Piglet.

With that said, here's a rather clumsy but working solution (maybe Loïc can chip in on this later):

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
34
35
36
37
38
39
40
41
42
43
44
module V = Piglet.Validation

let notEmpty p = V.Is V.NotEmpty "Must be non-empty" p

let pwFields =
    let s = new Stream<string>(Result.Success "")

    Piglet.Return (fun pw1 pw2 -> (pw1, pw2))
    // create the Piglet from a stream whose Id we know in advance
    <*> (Piglet.Create s (fun f -> f s) |> notEmpty) 
    <*> Piglet.Yield ""
    |> V.Is (fun (pw1, pw2) -> pw1 = pw2) "Passwords must match."
    |> Piglet.Map fst
    |> Piglet.TransmitReaderMapResult (function
        | Success s -> Success s
        // only propagate errors that are from the right stream
        | Failure f -> f |> List.filter (fun e -> e.Source <> s.Id) |> Failure)

let registerPiglet =
    Piglet.Return (fun username pw -> (username, pw))
    <*> (Piglet.Yield "" |> notEmpty)
    <*> pwFields
    |> Piglet.WithSubmit
    |> Piglet.Run (fun (username, pw) ->
        WebSharper.JavaScript.Console.Log (username + "," + pw))

let renderPiglet () =
  registerPiglet
  |> Piglet.Render (fun username pw1 pw2 matchingPw submit ->
        let mkControl lbl s (es : Reader<string>) =
            Div [
                Label [ Text lbl ] -< [
                    Controls.Input s
                    Span [Attr.Style "color:red"]
                    |> Controls.ShowErrors (es.Through submit)
                        (fun errors -> List.map Text errors)
                ]
            ]
        Div [
            mkControl "Username" username username
            mkControl "Password" pw1 pw1
            mkControl "Confirm password" pw2 matchingPw
            Div [ Controls.Submit submit ]
        ])
By on 7/16/2015 1:58 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