lonelyelk
lonelyelk

Reputation: 578

How to update a date field in elm model

I'm making an interface that allows to pick a date and a time. So the first thing would be to store said date in a model field date: Date. Than I would have for example a DatePicker to select a year-month-day part. For hours and minutes I guess I need two input fields or select fields or counter fields or whatever with onInput event trigger.

The question is: how do I proceed on said event? How do I update my date in the model if only hour or minute number changed?

HourChange hour ->
    { model | date = ...

Upvotes: 1

Views: 795

Answers (2)

Simone
Simone

Reputation: 21272

The answer really depends on what kind of datepicker you need; there are many ways of implementing one.

Just as an example, here's how you could leverage the HTML5's datepicker and timepicker (Elm 0.18):

import Html exposing (..)
import Html.Attributes exposing (type_)
import Html.Events exposing (onInput)


main =
    Html.beginnerProgram
        { model = initialModel
        , view = view
        , update = update
        }


-- MODEL

type alias Model =
    { date : String
    , time : String
    }


initialModel : Model
initialModel =
    { date = ""
    , time = ""
    }


-- UPDATE

type Msg
    = ChangeDate String
    | ChangeTime String


update : Msg -> Model -> Model
update msg model =
    case msg of
        ChangeDate newDate ->
            { model | date = newDate }

        ChangeTime newTime ->
            { model | time = newTime }


-- VIEW

view : Model -> Html Msg
view model =
    div []
        [ input [ type_ "date", onInput ChangeDate ] []
        , input [ type_ "time", onInput ChangeTime ] []
        , text (toString model)
        ]

The thing is, this may or may not be what you want. For example you may want a smarter datepicker, or a better one in terms of usability. The example above just demonstrates one of the possible ways.

There are also Elm libraries that may help you achieve your needs. See for example elm-datepicker.

Upvotes: 2

Chad Gilbert
Chad Gilbert

Reputation: 36375

You have a few options, but each of them will require constructing a new Date value by pulling each date part out of your current model.date value.

There is a package called rluiten/elm-date-extra which exposes a dateFromFields function that lets you specify each date part. Using this library, your code would look something like this:

import Date exposing (..)
import Date.Extra.Create exposing (dateFromFields)

...

HourChange hour ->
    { model | date =
        dateFromFields
               (year model.date)
               (month model.date)
               (day model.date)
               hour
               (minute model.date)
               (second model.date)
               (millisecond model.date)
    }

The core Date package currently supports creating dates from strings (or time) only. You could write the same sort of function as dateFromFields by concatenating together a string date, but it might be easier just to import that elm-date-extra package.

Upvotes: 2

Related Questions