Last active
February 14, 2017 05:02
-
-
Save kyasu1/edecc747f5339db69abcbab4d37102c8 to your computer and use it in GitHub Desktop.
A date input with separated fields for using with elm-form
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| module DateInput exposing (view, validate) | |
| import Html exposing (..) | |
| import Html.Attributes exposing (..) | |
| import Html.Events exposing (onInput, onFocus, onBlur) | |
| import Regex | |
| import Form exposing (InputType(..)) | |
| import Form.Field exposing (FieldValue(..)) | |
| import Form.Validate | |
| import Form.Error as Error | |
| import Date exposing (Date) | |
| import Date.Extra as Date | |
| view : Form.FieldState e String -> Html Form.Msg | |
| view state = | |
| div [] | |
| [ span [] | |
| [ input | |
| [ type_ "text" | |
| , onInput (yearToDateJa state) | |
| , onFocus (Form.Focus state.path) | |
| , onBlur (Form.Blur state.path) | |
| , value (state.value |> Maybe.map stringToYear |> Maybe.withDefault "") | |
| ] | |
| [] | |
| --, span [ class [ MyCss.Label ] ] [ text "年" ] | |
| , input | |
| [ type_ "text" | |
| , onInput (monthToDate state) | |
| , onFocus (Form.Focus state.path) | |
| , onBlur (Form.Blur state.path) | |
| , value (state.value |> Maybe.map stringToMonth |> Maybe.withDefault "") | |
| ] | |
| [] | |
| -- , span [ class [ MyCss.Label ] ] [ text "月" ] | |
| , input | |
| [ type_ "text" | |
| , onInput (dayToDate state) | |
| , onFocus (Form.Focus state.path) | |
| , onBlur (Form.Blur state.path) | |
| , value (state.value |> Maybe.map stringToDay |> Maybe.withDefault "") | |
| ] | |
| [] | |
| -- , span [ class [ MyCss.Label ] ] [ text "日" ] | |
| ] | |
| ] | |
| stringToYear : String -> String | |
| stringToYear isoDate = | |
| case String.split "-" isoDate of | |
| [ y, _, _ ] -> | |
| y | |
| _ -> | |
| "" | |
| filterYear : String -> String | |
| filterYear year = | |
| let | |
| year_ = | |
| "0000" ++ year |> String.right 4 | |
| in | |
| if validateYear year_ then | |
| year_ |> String.toUpper | |
| else | |
| String.dropRight 1 year | |
| validateYear : String -> Bool | |
| validateYear year = | |
| Regex.contains (Regex.regex "^[0-9]{0,4}$") year | |
| yearToDateJa : Form.FieldState e String -> String -> Form.Msg | |
| yearToDateJa state year = | |
| let | |
| year_ = | |
| filterYear year | |
| in | |
| case state.value of | |
| Just date -> | |
| let | |
| newDate = | |
| case String.split "-" date of | |
| [ y, m, d ] -> | |
| concatDate year_ m d | |
| _ -> | |
| concatDate year_ "" "" | |
| in | |
| Form.Input state.path Text (String newDate) | |
| Nothing -> | |
| Form.Input state.path Text (String (concatDate year_ "" "")) | |
| stringToMonth : String -> String | |
| stringToMonth date = | |
| case String.split "-" date of | |
| [ _, m, _ ] -> | |
| m | |
| _ -> | |
| "" | |
| filterMonth : String -> String | |
| filterMonth month = | |
| let | |
| month_ = | |
| "00" ++ month |> String.right 2 | |
| in | |
| if validateMonth month_ then | |
| month_ | |
| else | |
| String.dropRight 1 month | |
| validateMonth : String -> Bool | |
| validateMonth month = | |
| if Regex.contains (Regex.regex "^[0-9]{0,2}$") month then | |
| case String.toInt month of | |
| Ok value -> | |
| if value >= 1 && value <= 12 then | |
| True | |
| else | |
| False | |
| Err _ -> | |
| False | |
| else | |
| False | |
| monthToDate : Form.FieldState e String -> String -> Form.Msg | |
| monthToDate state month = | |
| let | |
| month_ = | |
| filterMonth month | |
| in | |
| case state.value of | |
| Just date -> | |
| let | |
| newDate = | |
| case String.split "-" date of | |
| [ y, m, d ] -> | |
| concatDate y month_ d | |
| _ -> | |
| concatDate "" month_ "" | |
| in | |
| Form.Input state.path Text (String newDate) | |
| Nothing -> | |
| Form.Input state.path Text (String (concatDate "" month_ "")) | |
| stringToDay : String -> String | |
| stringToDay date = | |
| case String.split "-" date of | |
| [ _, _, d ] -> | |
| d | |
| _ -> | |
| "" | |
| dayToDate : Form.FieldState e String -> String -> Form.Msg | |
| dayToDate state day = | |
| let | |
| day_ = | |
| filterDay day | |
| in | |
| case state.value of | |
| Just date -> | |
| let | |
| newDate = | |
| case String.split "-" date of | |
| [ y, m, d ] -> | |
| concatDate y m day_ | |
| _ -> | |
| concatDate "" "" day_ | |
| in | |
| Form.Input state.path Text (String newDate) | |
| Nothing -> | |
| Form.Input state.path Text (String (concatDate "" "" day_)) | |
| filterDay : String -> String | |
| filterDay day = | |
| let | |
| day_ = | |
| "00" ++ day |> String.right 2 | |
| in | |
| if validateDay day_ then | |
| day_ | |
| else | |
| String.dropRight 1 day | |
| validateDay : String -> Bool | |
| validateDay day = | |
| if Regex.contains (Regex.regex "^[0-9]{0,2}$") day then | |
| case String.toInt day of | |
| Ok value -> | |
| if value >= 1 && value <= 31 then | |
| True | |
| else | |
| False | |
| Err _ -> | |
| False | |
| else | |
| False | |
| validate : Form.Validate.Validation e Date | |
| validate field = | |
| case Form.Field.asString field of | |
| Just date -> | |
| case Date.fromIsoString date of | |
| Just date_ -> | |
| if (Date.day date_) == (date |> String.right 2 |> String.toInt |> Result.withDefault 0) then | |
| Result.Ok date_ | |
| else | |
| Result.Err (Error.value Error.InvalidDate) | |
| Nothing -> | |
| Result.Err (Error.value Error.InvalidDate) | |
| Nothing -> | |
| Result.Err (Error.value Error.InvalidDate) | |
| concatDate : String -> String -> String -> String | |
| concatDate y m d = | |
| y ++ "-" ++ m ++ "-" ++ d |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| module Main exposing (..) | |
| import Html exposing (..) | |
| import Html.Attributes exposing (..) | |
| import Html.Events exposing (..) | |
| import Form exposing (Form) | |
| import Form.Field as Field | |
| import Form.Validate as Validate exposing (..) | |
| import Form.Input as Input | |
| import Date exposing (Date) | |
| import DateInput | |
| type alias Customer = | |
| { id : String | |
| , date : Date | |
| } | |
| type alias Model = | |
| { form : Form () Customer } | |
| type Msg | |
| = NoOp | |
| | FormMsg Form.Msg | |
| init : ( Model, Cmd Msg ) | |
| init = | |
| ( { form = Form.initial [] validation }, Cmd.none ) | |
| validation : Validation () Customer | |
| validation = | |
| map2 Customer | |
| (field "id" string) | |
| (field "date" DateInput.validate) | |
| update : Msg -> Model -> ( Model, Cmd Msg ) | |
| update msg ({ form } as model) = | |
| case msg of | |
| NoOp -> | |
| ( model, Cmd.none ) | |
| FormMsg formMsg -> | |
| { model | form = Form.update validation formMsg form } ! [] | |
| view : Model -> Html Msg | |
| view { form } = | |
| Html.map FormMsg (formView form) | |
| formView : Form () Customer -> Html Form.Msg | |
| formView form = | |
| let | |
| date = | |
| Form.getFieldAsString "date" form | |
| in | |
| div [] | |
| [ DateInput.view date | |
| , Input.dumpErrors form | |
| ] | |
| main = | |
| Html.program | |
| { init = init | |
| , update = update | |
| , view = view | |
| , subscriptions = \_ -> Sub.none | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment