Date picker
module DatePicker exposing (..)

{-| This example uses fabhof/elm-ui-datepicker and justinmimbs/date packages.
-}

import Browser
import Date exposing (Date)
import DatePicker exposing (ChangeEvent(..))
import Element exposing (..)
import Element.Background as Background
import Element.Border as Border
import Element.Input as Input
import Html exposing (Html)
import Task


type alias Model =
    { date : Maybe Date
    , dateText : String
    , pickerModel : DatePicker.Model
    }


type Msg
    = UserChangedDatePicker ChangeEvent
    | RuntimeReturnedDate Date


view : Model -> Html Msg
view model =
    layout
        [ paddingEach { top = 50, bottom = 0, left = 0, right = 0 }
        ]
    <|
        DatePicker.input [ centerX ]
            { onChange = UserChangedDatePicker
            , selected = model.date
            , text = model.dateText
            , label = Input.labelAbove [] <| text "Choose a date"
            , placeholder = Just <| Input.placeholder [] <| text "yyyy-mm-dd"
            , settings = DatePicker.defaultSettings
            , model = model.pickerModel
            }


init : ( Model, Cmd Msg )
init =
    ( { date = Nothing
      , dateText = ""
      , pickerModel = DatePicker.init
      }
    , Task.perform RuntimeReturnedDate Date.today
    )


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        UserChangedDatePicker changeEvent ->
            case changeEvent of
                DateChanged date ->
                    -- update both date and text
                    ( { model
                        | date = Just date
                        , dateText = Date.toIsoString date
                      }
                    , Cmd.none
                    )

                TextChanged text ->
                    ( { model
                        | date =
                            case Date.fromIsoString text of
                                Ok newDate ->
                                    Just newDate

                                Err _ ->
                                    model.date
                        , dateText = text
                      }
                    , Cmd.none
                    )

                PickerChanged subMsg ->
                    -- internal stuff changed
                    -- call DatePicker.update
                    ( { model
                        | pickerModel =
                            model.pickerModel
                                |> DatePicker.update subMsg
                      }
                    , Cmd.none
                    )

        RuntimeReturnedDate today ->
            ( { model
                | pickerModel =
                    model.pickerModel
                        |> DatePicker.setToday today
              }
            , Cmd.none
            )


main : Program () Model Msg
main =
    Browser.element
        { init = \_ -> init
        , view = view
        , update = update
        , subscriptions = \_ -> Sub.none
        }
Would you like to forget CSS and have fun building UIs with elm-ui instead?
📢 My in-depth guide
elm-ui: The CSS Escape Plan
is now available in early access.
🎁 Get a walkthrough of all elm-ui features and an expanded set of examples.
🛠 I'm still adding content but you can start learning right now 👇
elm-ui: The CSS Escape Plan