I have previously added validation icon/message support to UI.Next.Formlets (there is a pull request pending). Now I want to add a per Input submitter to delay validation until the user has finished typing. I thus need to pull out the existing Input from the formlet, and add a Submitter trigger to the OnChange event of the input. Importing WebSharper.UI.Next.Client does unfortunately not help, the On-methods of Elt objects are still "server-side". Here is the actual implementation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
let ValidateOnChange (flX : Formlet<'T>)  =
	let flx = flX.Data()
    let sb = Submitter.Create flx.View (Failure [])
    let tf (_ : Dom.Element) (_ : Dom.Event) = sb.Trigger ()
    let ls =
        match flx.Layout with 
        | [l] -> 
            match l.Shape with
            | Item x ->
               match x with
               | :? Elt as x -> 
                   [{l with Shape = Item (x.OnChhange tf)}]
               | _ -> [l]
            | _ -> [l] 
        | l -> l
    Formlet (fun () ->
       {
           View = sb.View
           Layout = ls
       }
    )

P.S. I really like the Formlets because they are so simple, compact and convenient for quick and dirty work. The UI.Next.Forms are very nice too, but much more verbose. D.S.

By on 4/5/2016 2:46 AM ()

I figured it out! Going through the UI.Next sources I found the DocExtensions type, which contains a static method OnChange with the correct (client-side) signature. I have not tested it yet, but I think it will do the trick.

Regarding the gung-ho style type match, I agree it's not optimal. But it relies on the fact that in UI.Next.Formlets the Item case will always contain an input type element. But if you have a better suggestion, I'd be happy to know!

By on 4/5/2016 4:24 AM ()

Yes, it's an extension method on Elt whoch should be available once you opened the WebSharper.UI.Next.Client namespace so I'm not sure why you don't see it after opening that.

By on 4/5/2016 4:55 AM ()

I think it's because the On* methods are members of the type DocExtensions, whereas EltExtensions is an AutoOpened module which only exposes the Elt type. I'm not sure why the extensions are implemented as a type rather than as a module (which can be AutoOpened), but there is probably a good reason for this.

By on 4/5/2016 5:39 AM ()

We use C# extension methods for potential future C# support and use types instead of modoules to be able to have overrides on the members.

By on 4/5/2016 6:54 AM ()

Yes, of course! Thank you for all the help!

By on 4/5/2016 10:54 AM ()

Thanks, that explains it. I was a bit puzzled by the need for a quotation. I need to add a handler to an existing Doc.Input , but 'm having trouble accessing/finding the client side methods. Here is an actual snippet of my (client-side) code

1
2
3
match x with
| :? Elt as e -> e.OnChange (fun _ _ -> ())
| _ -> x

But this does not type check due to the missing quotations.

By on 4/5/2016 2:14 AM ()

Forgot to mention you have to import WebSharper.UI.Next.Client to have the client side extension methods.

P.S: I'm not exactly sure what you are trying to do but note that it's usually not a good practice to use typechecks like that. More often than not, you can go about your code in a different way that will be much more idiomatic.

By on 4/5/2016 2:24 AM ()

On* methods have an overload for the client and server side respectively. There is one which takes a quotation which is for the server to use and IIRC it may only contain a top level function in a JavaScript annotated module (so a client side module). There is another one which, in your case, would have the following type: OnChange : (Dom.Element -> Dom.Event -> unit) -> Elt. You can also use the on.* family of attributes when creating an element: spanAttr [on.click (fun el ev -> ())] [text "some span"], which work the same way as the e.On* methods.

By on 4/5/2016 1:59 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