fsbolero / Bolero

Bolero brings Blazor to F# developers with an easy to use Model-View-Update architecture, HTML combinators, hot reloaded templates, type-safe endpoints, advanced routing and remoting capabilities, and more.
https://fsbolero.io
Apache License 2.0
1.06k stars 54 forks source link

DatePicker Demo #101

Open CraigChamberlain opened 4 years ago

CraigChamberlain commented 4 years ago

Hi,

Is there any chance we could have an example of a date picker in the demo app?

I'm trying to get head around it but going to give in for the night. If I ever work it out I'd be happy to have a go making a pull request if it would be of interest.

Thanks

Craig

CraigChamberlain commented 4 years ago

The following works to an extent but I seem to only be able to bind in string format? Also the date picker looses it's value on update.

/// The Elmish application's model.
type Model =
    {
        gregorianDate : DateTime
        solarLunarDate: string option
        error: string option
    }

let initModel =
    {
        gregorianDate = DateTime.Now
        solarLunarDate = None
        error = None
    }

/// Remote service definition.
type SolarLunarDateService =
    {
        /// Get the list of all books in the collection.
        getSolarLunarDate: DateTime -> Async<string>

    }

    interface IRemoteService with
        member this.BasePath = "/solar-lunar-date"

/// The Elmish application's update messages.
type Message =
    | SetDate of string
    | GetSolarLunarDate of DateTime
    | RecvSolarLunarDate of string
    | Error of exn
    | ClearError

let update remote message (model:Model) =
    match message with
    | SetDate d ->
        let date = DateTime.Parse d
        { model with solarLunarDate = None; gregorianDate =  date }, Cmd.ofMsg (GetSolarLunarDate date)
    | GetSolarLunarDate d ->
        let cmd = Cmd.ofAsync remote.getSolarLunarDate d RecvSolarLunarDate Error
        model, cmd    
    | RecvSolarLunarDate solarLunarDate ->
        { model with solarLunarDate = Some solarLunarDate }, Cmd.none
    | Error exn ->
        { model with error = Some exn.Message }, Cmd.none
    | ClearError ->
        { model with error = None }, Cmd.none

type Main = Template<"wwwroot/main.html">

let homePage model dispatch =
    Main
        .Home()
        .GregorianDate(string model.gregorianDate, (fun d -> dispatch (SetDate d) ))
        .SolarLunarDate(
            cond model.solarLunarDate <| function
            | None -> empty
            | Some string -> Text string

        )
        .Elt()

      <template id="Home">
        <h1 class="title">A simple counter</h1>
        <p>
          <input type="date" id="gregorianDate" class="input" bind-onchange="${GregorianDate}" >
          ${SolarLunarDate}
        </p>
      </template>
BentTranberg commented 4 years ago

Have a look in my ExploreBolero repo, more specifically the BlazorDates page. I am not sure I've done it correctly, but it's been working well for a long time. Would be happy if somebody could to a quick code review of the relevant code, so that any mistakes I've possibly made can be corrected.

What I really want, is to use the date and time pickers from Bulma Extensions, but I haven't found a way to integrate them yet. Not enough research time available. They look and feel better, and have date range selections.

Tarmil commented 4 years ago

I found out that the built-in binders in Blazor for various types, including DateTime and DateTimeOffset with custom format and CultureInfo, could be easily added to Bolero. I just need to figure out the best API to expose them: see #102.

CraigChamberlain commented 4 years ago

Thanks @BentTranberg,a really useful resource. I see you have a dependency NodaTimePicker.
@Tarmil, is it not yet supported to bind to the razor time picker?

Tarmil commented 4 years ago

@CraigChamberlain It is supported now with Bolero 0.11.

CraigChamberlain commented 4 years ago

That's great news. Thanks.

C

On Sun, 26 Jan 2020, 10:50 Loïc Denuzière, notifications@github.com wrote:

@CraigChamberlain https://github.com/CraigChamberlain It is supported now with Bolero 0.11.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/fsbolero/Bolero/issues/101?email_source=notifications&email_token=ALRDEQ6S37AZVPBZO25JDFTQ7VTIJA5CNFSM4JTDVV7KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEJ5Q5VI#issuecomment-578490069, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALRDEQ7W2W3722RB3O6XWTTQ7VTIJANCNFSM4JTDVV7A .

CraigChamberlain commented 4 years ago

Hi

I've just given this another go. I can make get the parts to talk but the value of the form gets wiped out every time the page updates?

image

    let selectToDate = 
        form [] [
            input [ attr.``type`` "date"
                    attr.value (model.gregorianDate.ToString("yyyy-MM-dd"))
                    attr.max "2081-01-01"
                    attr.min "1700-12-31"
                    bind.change.dateTime model.gregorianDate (fun d -> d |> SetDate |> dispatch)
                  ]
        ]

Thanks

Craig

Tarmil commented 4 years ago

@CraigChamberlain bind.change.dateTime sets the value, so you don't need the corresponding attr.value.

Also, be careful with buttons inside form elements: by default, the button becomes a type submit, which submits the form (and so refreshes the page, if the form doesn't define an action). Make sure to set attr.``type`` "button" on your button to prevent this.

CraigChamberlain commented 4 years ago

Hi, So you are right about button type but I had already discovered that. Also omitting the value has really no difference in Firefox and it works entirely differently in chrome anyway. After reading around I think date pickers should probably implement some kind of ui component as html5 date-picker is not ready to use and is inconsistent across browsers.

Can you point me in the direction of any ui libraries that have been published for bolero? I think I might have to send a while learning razor mvc to get a proper start with bolero. Feels like it's a prerequisite knowledge.