Hi, I was trying to do the same and came up with this:

1
2
3
4
5
6
7
8
9
10
11
12
13
let selectedDate = Var.Create (Date(2015,7,8))
let selectedDateView = selectedDate |> View.FromVar |> View.Map(fun d -> d.GetFullYear().ToString() + "-" + d.GetMonth().ToString() + "-" + d.GetDate().ToString())
        
let el = Html.Client.Tags.Div []
let datepicker = Datepicker.New(el)
datepicker.OnSelect (fun dt _ ->
           Var.Set selectedDate dt
)
datepicker.Render()
let datepickerDoc = Doc.Static (el.Dom)
       
Div0 [datepickerDoc; Doc.TextView selectedDateView]
|> Doc.RunById "main"

It does seem to work, but I'm not sure how well that .Render() plays with the Doc lifecycle.

By on 7/10/2015 11:37 AM ()

You are right, my problem was calling render on the wrong element so with everything put together this seems like the best solution. Only thing missing here is that if you modify the underlying Var in your code, it doesn't update the UI. This is what i have now using System.DateTime for convinience and also updating the date picker when the Var changes without using View.Sink. It only renders the picker once in this case. I'm not entierly sure how it would react to DOM updates on the Doc tree:

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
open System
open WebSharper.JQueryUI
open WebSharper.JavaScript
open WebSharper.UI.Next
open WebSharper.UI.Next.Notation

let EmbedPagelet (pagelet : WebSharper.Html.Client.Element) render =
    pagelet.Dom
    |> View.Const
    |> View.Map (fun el ->
        render ()
        Doc.Static el)
    |> Doc.EmbedView 

let DatePicker (date: Var<DateTime>) =
    let el = Html.Client.Tags.Div []
    let picker = Datepicker.New(el)
    picker.OnSelect <| fun dt _ ->
        if !date <> dt.Self then
            date := dt.Self

    let doc = EmbedPagelet el picker.Render

    date.View
    |> View.Map (fun newValue ->
        let currentDate = picker.GetDate()
        if currentDate <> null && newValue <> currentDate.Self then
            picker.SetDate newValue.JS
        doc)
    |> Doc.EmbedView
By on 7/11/2015 3:05 AM ()

Phew, this was quite a hard one. There seem to be some funky things going on in the JQuery.UI bindings which we will have to look into. For the time being you can solve this with a bit of a trickery:

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
let embedPagelet (pagelet : WebSharper.Html.Client.Element) =
    pagelet.Dom
    |> View.Const
    |> View.Map (fun el ->
        pagelet.Render ()
        Doc.Static el)
    |> Doc.EmbedView  

let createDatePicker (date: Var<DateTime>) =
    let pickerEl = Html.Client.Tags.Div []

    // Some ugly trickery to initialize the DatePicker with the
    // right callback function.
    // FuncWithArgs basically tells the compiler that the function should
    // be compiled into a JavaScript function taking two arguments instead of
    // one taking tuple as an argument.
    // Also we get the date in string so we have to parse it first.
    let cfg = DatepickerConfiguration()
    cfg?onSelect <- FuncWithArgs(fun (newValue : string, datepicker) ->
        let newValue = Date(newValue)
        let dateTime = newValue.Self // use JavaSript.Date#Self to convert it to DateTime
        if date.Value <> dateTime then Var.Set date dateTime)
        
    let picker = JQueryUI.Datepicker.New(pickerEl, cfg)

    // Don't use View.Sink because it may lead to memory leaks.
    // Instead execute the side-effect inside a View.Map tying the update to the
    // lifetime of the Doc element instead of making it global.
    date.View
    |> View.Map (fun newValue ->
        let currentDate = picker.GetDate()
        if currentDate <> null && newValue <> currentDate.Self then
            picker.SetDate newValue.JS // use DateTime#JS to convert it to JavaScript.Date
        embedPagelet pickerEl)
    |> Doc.EmbedView

I didn't quite understand the purpose of the inner Var in your snippet but if you want to do what I think you want to then having just the parameter should suffice.

By on 7/10/2015 9:22 AM ()

Yes you're right, the Var in the snippet was a typo.

I managed to solve it in a different way without resorting to strings, although I still need to get rid of the View.Sink somehow. I think the problem is to do with Render() being called on the wrong element.

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
let EmbedPageletWithCustomRender (pagelet : WebSharper.Html.Client.Element) (f:unit -> unit)=
    pagelet.Dom
    |> View.Const
    |> View.Map (fun el ->          
        f()
        Doc.Static el)
    |> Doc.EmbedView

let EmbedPagelet (pagelet : WebSharper.Html.Client.Element) =
    EmbedPageletWithCustomRender pagelet (fun () -> pagelet.Render())

let createDatePicker (date:Var<DateTime>) =
  let toDateTime (d:JavaScript.Date) =
    DateTime(d.GetFullYear(), d.GetMonth() + 1, d.GetDate())      

  let toJsDate (d:DateTime) =
    JavaScript.Date(d.Year, d.Month - 1, d.Day)

  let pickerElement = Html.Client.Tags.Input [Html.Client.Attr.Type "text"]
  let config = JQueryUI.DatepickerConfiguration()
  config.DateFormat <- "d MM yy"

  let picker = JQueryUI.Datepicker.New(pickerElement)

  date.View
  |> View.Sink (fun newValue ->
      let currentDate = picker.GetDate() |> toDateTime
      if newValue <> currentDate then picker.SetDate(newValue |> toJsDate))

  Doc.EmbedPageletWithCustomRender pickerElement (fun () ->      

    picker |> Html.Client.Operators.OnAfterRender(fun _ ->
      picker.SetDate(toJsDate date.Value)
      picker.Option config
      )

    picker.OnSelect(fun newValue datepicker ->
        let datetime = toDateTime newValue
        if date.Value <> datetime then
          Var.Set date datetime)      

    picker.Render()
    )      
By on 7/10/2015 10:43 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