This module provides a styled date picker for Elm. You can check out the demo here.
To alter the color theme edit ./styl/Variables.styl
, then run
npm install && npm run build-styles
.
This library depends heavily on justinmimbs/date as
this provides a nice RD based wrapper around Dates that is agnostic to time/timezone, which is better suited for
calendars. See the documentation there for any specific handling of the Date
type.
You will first need to add the DatePicker.Msg
to the type consumed by your update
function so
it recognizes this type.
import DatePicker
...
type Msg
= FireZeMissiles
| DatePickerMsg DatePicker.Msg
init : String -> ( Model, Platform.Cmd.Cmd Msg )
DatePicker.init
returns an initialized record of DatePicker.Model
. Do not throw out the returned command!
The command is used to get today's current date which the date picker uses as the default for display.
The string passed as the first argument must be a unique id
for the date picker.
import DatePicker
init : ( Model, Cmd Msg )
init =
let
( datePickerData, datePickerInitCmd ) =
DatePicker.init "my-datepicker-id"
in
( { datePickerData = datePickerData
, selectedDate = Nothing
}
, Cmd.map DatePickerMsg datePickerInitCmd
)
initFromDate : String -> Date -> Model
Initialize a date picker given a date to start from.
update : Msg -> Model -> ( Model, Platform.Cmd.Cmd Msg )
Use DatePicker.update
to create updated date picker models from any message events.
For a nice full working example check out the demo source here
import DatePicker exposing (Msg(..))
...
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
NoOp ->
( model, Cmd.none )
DatePickerMsg datePickerMsg ->
let
(updatedPicker, pickerCmd) =
DatePicker.update
datepickerMsg
model.datePickerData
in
({ model
| datePickerData = updatedPicker
, selectedDate = datePickerData.selectedDate
}
, Cmd.map DatePickerMsg pickerCmd
)
{ id : String
, today : Maybe Date
, indexDate : Maybe Date
, currentMonthMap : Maybe (List ( Basics.Int
, Date ))
, previousMonthMap : Maybe (List ( Basics.Int
, Date ))
, selectedDate : Maybe Date
, previousSelectedDate : Maybe Date
, monthChange : MonthChange
, selectionMode : SelectionMode
, yearList : Maybe (List Basics.Int)
}
The DatePicker.Model
type needs to be added to any data structure that requires a picker instance
import DatePicker
...
type alias Model =
{ datePickerData : DatePicker.Model
}
}
This is mostly an opaque type you don't have to worry about, though there are some important fields you will want to use:
today
is the default "selected" day of the picker before the user has actually clicked to "select" a day.
This is needed so the head display isn't empty before the user has selected anything, without forcing there be a default selected date of "today".indexDate
is a date used to track which month the calendar is currently showing. Do not set this directly. Use the setIndexDate
helperselectedDate
is the last date the user clicked on in the calendar that was selectableselectionMode
determines whether the user sees the Calendar
or the YearPicker
view : Model -> Props -> Html Msg
The main view for the date picker. Use Html.map
so the returned type doesn't conflict with
your view's type.
import DatePicker
...
view : Model -> Html Msg
view model =
Html.map DatePickerMsg <|
DatePicker.view
model.datePickerData
DatePicker.defaultProps
{ canSelectYear : Basics.Int -> Basics.Bool
, canSelectMonth : Basics.Int -> Time.Month -> Basics.Bool
, canSelectDate : Date -> Basics.Bool
, hideFooter : Basics.Bool
, monthDisplay : Time.Month -> String
, daySymbol : Time.Weekday -> String
, selectedDateDisplay : Maybe Date -> Date -> String
, okButtonText : String
, cancelButtonText : String
}
The second argument passed to DatePicker.view
. These are configuration properties
that generally determine the range of selectable dates. Extend off DatePicker.defaultProps
to avoid having to define all of these when you only wish to configure a few.
Property Descriptions
given the year, return whether this year is allowed to be selected
canSelectYear : Int -> Bool
given the year and the month, return whether this month is allowed to be selected
canSelectMonth : Int -> Month -> Bool
given the date, return whether this is allowed to be selected
canSelectDate : Date -> Bool
should the footer of the calendar with the "CANCEL" and "OK" buttons display
hideFooter : Bool
text for the "OK" button which is enabled whenever a date is selected. defaults to "OK"
okButtonText : String
text for the "CANCEL" button. Defaults to "CANCEL"
cancelButtonText : String
return whatever text to show given the month (this is just below the calendar header)
monthDisplay : Time.Month -> String
return whatever text (generally a single letter or two) to show given the weekday (these are the small letters the top of the month)
daySymbol : Time.Weekday -> String
return whatever text to show given the selected Date (This is the large display text on the calendar header) The first date is the "selectedDate" which may not yet be defined. The second is the "indexDate" which is the current placeholder date being used (generally set to today's date by default)
selectedDateDisplay : Maybe Date -> Date -> String
defaultProps : Props
Use the default props if you don't want to support any sort of configuration. These mostly center around limiting the user to a specific selection range of dates. By default, nothing is restricted.
Here's an example of how you might configure these:
getDatePickerProps : DatePicker.Props
getDatePickerProps =
let
defaultProps =
DatePicker.defaultProps
in
{ defaultProps
| canSelectYear = \year -> year < 2020
, okButtonText = "CONFIRM"
}
setIndexDate : Model -> Date -> Model
Takes any of type DatePicker.Model
and returns a new one with the given index date. It is
important to not just set indexDate directly as this will not refresh the data to completely
reflect this
Represents the current mode the picker is set to
type SelectionMode
= Calendar
| YearPicker