Add form data parser for new type.

This commit is contained in:
Dillon Kearns 2022-07-21 15:31:16 +02:00
parent cdfca81338
commit c2f0e2922a
4 changed files with 205 additions and 9 deletions

View File

@ -196,8 +196,7 @@ data routeParams =
action : RouteParams -> Parser (DataSource (Server.Response.Response ActionData ErrorPage))
action routeParams =
--Request.formData [ form ]
Request.skip "todo"
Request.formData2 [ form ]
|> Request.map
(\userResultData ->
userResultData

View File

@ -17,7 +17,9 @@ module Form exposing
-- subGroup
, errorsForField2
, field2
, hiddenField2
, init2
, runOneOfServerSideWithServerValidations2
, toDynamicTransitionNew
)
@ -86,6 +88,7 @@ import DataSource exposing (DataSource)
import Dict exposing (Dict)
import Dict.Extra
import Form.Field as Field exposing (Field(..))
import Form.FieldView
import Form.Validation as Validation exposing (Validation)
import Html exposing (Html)
import Html.Attributes as Attr
@ -507,6 +510,88 @@ field2 name (Field fieldParser kind) (FormNew definitions parseFn toInitialValue
)
{-| -}
hiddenField2 :
String
-> Field error parsed data kind constraints
-> FormNew error (Validation error parsed Form.FieldView.Hidden -> parsedAndView) data
-> FormNew error parsedAndView data
hiddenField2 name (Field fieldParser _) (FormNew definitions parseFn toInitialValues) =
FormNew
(( name, HiddenField )
:: definitions
)
(\maybeData formState ->
let
( maybeParsed, errors ) =
fieldParser.decode rawFieldValue
( rawFieldValue, fieldStatus ) =
case formState.fields |> Dict.get name of
Just info ->
( Just info.value, info.status )
Nothing ->
( Maybe.map2 (|>) maybeData fieldParser.initialValue, Form.NotVisited )
thing : Pages.Internal.Form.ViewField Form.FieldView.Hidden
thing =
{ value = rawFieldValue
, status = fieldStatus
, kind = ( Form.FieldView.Hidden, fieldParser.properties )
}
parsedField : Validation error parsed Form.FieldView.Hidden
parsedField =
Pages.Internal.Form.Validation (Just thing) (Just name) ( maybeParsed, Dict.empty )
myFn :
{ result : Dict String (List error)
, parsedAndView : Validation error parsed Form.FieldView.Hidden -> parsedAndView
, serverValidations : DataSource (List ( String, List error ))
}
->
{ result : Dict String (List error)
, parsedAndView : parsedAndView
, serverValidations : DataSource (List ( String, List error ))
}
myFn soFar =
let
serverValidationsForField : DataSource ( String, List error )
serverValidationsForField =
fieldParser.serverValidation rawFieldValue
|> DataSource.map (Tuple.pair name)
validationField : Validation error parsed Form.FieldView.Hidden
validationField =
parsedField
in
{ result =
soFar.result
|> addErrorsInternal name errors
, parsedAndView =
soFar.parsedAndView validationField
, serverValidations =
DataSource.map2 (::)
serverValidationsForField
soFar.serverValidations
}
in
formState
|> parseFn maybeData
|> myFn
)
(\data ->
case fieldParser.initialValue of
Just toInitialValue ->
( name, toInitialValue data )
:: toInitialValues data
Nothing ->
toInitialValues data
)
{-| -}
hiddenField :
String
@ -877,12 +962,6 @@ runServerSide2 :
List ( String, String )
-> Form error (Validation error parsed named) data (Context error data -> view)
-> ( Maybe parsed, DataSource (FieldErrors error) )
---> ( Maybe parsed, DataSource (List ( String, List error )) )
runServerSide2 rawFormData (Form _ parser _) =
let
parsed :
@ -918,6 +997,47 @@ runServerSide2 rawFormData (Form _ parser _) =
|> mergeResultsDataSource
{-| -}
runServerSide3 :
List ( String, String )
->
FormNew
error
{ all | combine : Validation error parsed kind }
data
-> ( Maybe parsed, DataSource (FieldErrors error) )
runServerSide3 rawFormData (FormNew _ parser _) =
let
parsed :
{ result : Dict String (List error)
, parsedAndView : { all | combine : Validation error parsed kind }
, serverValidations : DataSource (List ( String, List error ))
}
parsed =
parser Nothing thisFormState
thisFormState : Form.FormState
thisFormState =
{ initFormState
| fields =
rawFormData
|> List.map
(Tuple.mapSecond
(\value ->
{ value = value
, status = Form.NotVisited
}
)
)
|> Dict.fromList
}
in
{ result = ( parsed.parsedAndView.combine, parsed.result )
, serverValidations = parsed.serverValidations
}
|> mergeResultsDataSource
unwrapValidation : Validation error parsed named -> ( Maybe parsed, FieldErrors error )
unwrapValidation (Pages.Internal.Form.Validation viewField name ( maybeParsed, errors )) =
( maybeParsed, errors )
@ -980,6 +1100,38 @@ runOneOfServerSideWithServerValidations rawFormData parsers =
( Nothing, DataSource.succeed Dict.empty )
{-| -}
runOneOfServerSideWithServerValidations2 :
List ( String, String )
->
List
(FormNew
error
{ all | combine : Validation error parsed kind }
data
)
-> ( Maybe parsed, DataSource (FieldErrors error) )
runOneOfServerSideWithServerValidations2 rawFormData parsers =
case parsers of
firstParser :: remainingParsers ->
let
thing : ( Maybe parsed, DataSource (FieldErrors error) )
thing =
runServerSide3 rawFormData firstParser
in
case thing of
-- TODO should it try to look for anything that parses with no errors, or short-circuit if something parses regardless of errors?
( Just _, _ ) ->
thing
_ ->
runOneOfServerSideWithServerValidations2 rawFormData remainingParsers
[] ->
-- TODO need to pass errors
( Nothing, DataSource.succeed Dict.empty )
{-| -}
renderHtml :
List (Html.Attribute (Pages.Msg.Msg msg))

View File

@ -1,7 +1,7 @@
module Form.FieldView exposing
( Input(..), InputType(..), Options(..), input, inputTypeToString, radio, select, toHtmlProperties
, radioStyled, inputStyled
, input2
, Hidden(..), input2
)
{-|
@ -92,6 +92,10 @@ type Input
= Input InputType
type Hidden
= Hidden
{-| -}
type Options a
= Options (String -> Maybe a) (List String)

View File

@ -15,6 +15,7 @@ module Server.Request exposing
, map3, map4, map5, map6, map7, map8, map9
, Method(..), methodToString
, errorsToString, errorToString, getDecoder, ValidationError
, formData2
)
{-|
@ -948,6 +949,46 @@ formData formParsers =
)
{-| -}
formData2 :
List
(Form.FormNew
error
{ all | combine : Validation error combined kind }
data
)
-> Parser (DataSource (Result { fields : List ( String, String ), errors : Dict String (List error) } combined))
formData2 formParsers =
rawFormData
|> andThen
(\rawFormData_ ->
let
( maybeDecoded, errorsDataSource ) =
Form.runOneOfServerSideWithServerValidations2
rawFormData_
formParsers
in
errorsDataSource
|> DataSource.map
(\errors ->
case ( maybeDecoded, errors |> Dict.toList |> List.filter (\( _, value ) -> value |> List.isEmpty |> not) |> List.NonEmpty.fromList ) of
( Just decoded, Nothing ) ->
Ok decoded
( _, maybeErrors ) ->
Err
{ fields = rawFormData_
, errors =
maybeErrors
|> Maybe.map List.NonEmpty.toList
|> Maybe.withDefault []
|> Dict.fromList
}
)
|> succeed
)
{-| -}
rawFormData : Parser (List ( String, String ))
rawFormData =