From 647a18cf2849d3b75984f6b6a4cec7f940cdf117 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Mon, 10 Jan 2022 12:38:49 -0800 Subject: [PATCH] Show errors for radio inputs, and add required radio builder. --- examples/pokedex/src/Page/TailwindForm.elm | 16 +++-- src/Form.elm | 79 +++++++++++++++++----- 2 files changed, 73 insertions(+), 22 deletions(-) diff --git a/examples/pokedex/src/Page/TailwindForm.elm b/examples/pokedex/src/Page/TailwindForm.elm index 413ee482..6646d1cd 100644 --- a/examples/pokedex/src/Page/TailwindForm.elm +++ b/examples/pokedex/src/Page/TailwindForm.elm @@ -56,7 +56,7 @@ type alias NotificationPreferences = { comments : Bool , candidates : Bool , offers : Bool - , pushNotificationsSetting : Maybe PushNotificationsSetting + , pushNotificationsSetting : PushNotificationsSetting } @@ -72,7 +72,7 @@ defaultUser = { comments = False , candidates = False , offers = False - , pushNotificationsSetting = Nothing + , pushNotificationsSetting = PushNone } } @@ -307,7 +307,7 @@ form user = |> Form.appendForm (|>) (Form.succeed identity |> Form.with - (Form.radio + (Form.requiredRadio "push-notifications" ( ( "PushAll", PushAll ) , [ ( "PushEmail", PushEmail ) @@ -1023,7 +1023,7 @@ radioInput item { toLabel, toInput, errors } = ] -wrapPushNotificationsSection children = +wrapPushNotificationsSection errors children = Html.div [ css [ Tw.pt_6 @@ -1091,4 +1091,12 @@ wrapPushNotificationsSection children = ] ] ] + , Html.p + [ css + [ Tw.mt_2 + , Tw.text_sm + , Tw.text_red_600 + ] + ] + [ errors |> List.map Form.errorToString |> String.join "\n" |> Html.text ] ] diff --git a/src/Form.elm b/src/Form.elm index 31c4037f..441b7451 100644 --- a/src/Form.elm +++ b/src/Form.elm @@ -482,13 +482,10 @@ radio : { toInput : List (Html.Attribute Msg) , toLabel : List (Html.Attribute Msg) , errors : List Error - - -- TODO - --, item : item } -> view ) - -> (List view -> view) + -> (List Error -> List view -> view) -> Field (Maybe item) view {} radio name nonEmptyItemMapping toHtmlFn wrapFn = let @@ -528,9 +525,7 @@ radio name nonEmptyItemMapping toHtmlFn wrapFn = \_ fieldInfo info -> items |> List.map (\item -> toHtmlFn item (toRadioInputRecord name (toString item) info fieldInfo)) - |> wrapFn - - -- TODO should it be Err if Nothing? + |> wrapFn (info |> Maybe.map .errors |> Maybe.withDefault []) , decode = \raw -> raw @@ -540,20 +535,66 @@ radio name nonEmptyItemMapping toHtmlFn wrapFn = } +requiredRadio : + String + -> ( ( String, item ), List ( String, item ) ) + -> + (item + -> + { toInput : List (Html.Attribute Msg) + , toLabel : List (Html.Attribute Msg) + , errors : List Error + } + -> view + ) + -> (List Error -> List view -> view) + -> Field item view {} +requiredRadio name nonEmptyItemMapping toHtmlFn wrapFn = + let + itemMapping : List ( String, item ) + itemMapping = + nonEmptyItemMapping + |> List.NonEmpty.toList -{- - List.foldl - (\item formSoFar -> - required (rawRadio name toHtmlFn fromString) - formSoFar - ) - (succeed Nothing) - items + toString : item -> String + toString targetItem = + case nonEmptyItemMapping |> List.NonEmpty.toList |> List.filter (\( string, item ) -> item == targetItem) |> List.head of + Just ( string, _ ) -> + string + Nothing -> + "Missing enum" - rawRadio name toHtmlFn fromString = + fromString : String -> Maybe item + fromString string = + itemMapping + |> Dict.fromList + |> Dict.get string --} + items : List item + items = + itemMapping + |> List.map Tuple.second + in + Field + { name = name + , initialValue = Nothing + , type_ = "radio" + , required = True + , serverValidation = \_ -> DataSource.succeed [] + , toHtml = + -- TODO use `toString` to set value + \_ fieldInfo info -> + items + |> List.map (\item -> toHtmlFn item (toRadioInputRecord name (toString item) info fieldInfo)) + |> wrapFn (info |> Maybe.map .errors |> Maybe.withDefault []) + , decode = + \raw -> + raw + |> validateRequiredField + |> Result.andThen (fromString >> Result.fromMaybe (Error "Invalid radio option")) + , properties = [] + } submit : @@ -1102,7 +1143,9 @@ toHtml { pageReloadSubmit } toForm serverValidationErrors (Form fields decoder s [] else - [ Html.Events.onSubmit SubmitForm ] + [ Html.Events.onSubmit SubmitForm + , Attr.novalidate True + ] ] |> List.concat )