2022-01-01 23:50:03 +03:00
|
|
|
module Page.Form exposing (Data, Model, Msg, page)
|
|
|
|
|
|
|
|
import DataSource exposing (DataSource)
|
2022-01-04 08:17:07 +03:00
|
|
|
import Date exposing (Date)
|
2022-01-02 20:52:04 +03:00
|
|
|
import Dict exposing (Dict)
|
2022-01-01 23:50:03 +03:00
|
|
|
import Form exposing (Form)
|
2022-01-17 02:29:06 +03:00
|
|
|
import Form.Value
|
2022-01-01 23:50:03 +03:00
|
|
|
import Head
|
|
|
|
import Head.Seo as Seo
|
2022-01-03 21:07:06 +03:00
|
|
|
import Html exposing (Html)
|
|
|
|
import Html.Attributes as Attr
|
2022-01-01 23:50:03 +03:00
|
|
|
import Page exposing (Page, PageWithState, StaticPayload)
|
|
|
|
import PageServerResponse exposing (PageServerResponse)
|
|
|
|
import Pages.PageUrl exposing (PageUrl)
|
|
|
|
import Pages.Url
|
|
|
|
import Server.Request as Request exposing (Request)
|
|
|
|
import Shared
|
2022-01-04 08:17:07 +03:00
|
|
|
import Time
|
2022-01-01 23:50:03 +03:00
|
|
|
import View exposing (View)
|
|
|
|
|
|
|
|
|
|
|
|
type alias Model =
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
|
|
type alias Msg =
|
2022-01-06 01:09:37 +03:00
|
|
|
()
|
2022-01-01 23:50:03 +03:00
|
|
|
|
|
|
|
|
|
|
|
type alias RouteParams =
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
|
|
type alias User =
|
|
|
|
{ first : String
|
|
|
|
, last : String
|
|
|
|
, username : String
|
|
|
|
, email : String
|
2022-01-04 08:17:07 +03:00
|
|
|
, birthDay : Date
|
2022-01-04 22:47:57 +03:00
|
|
|
, checkbox : Bool
|
2022-01-01 23:50:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
defaultUser : User
|
|
|
|
defaultUser =
|
2022-01-02 05:35:36 +03:00
|
|
|
{ first = "Jane"
|
|
|
|
, last = "Doe"
|
|
|
|
, username = "janedoe"
|
|
|
|
, email = "janedoe@example.com"
|
2022-01-04 08:17:07 +03:00
|
|
|
, birthDay = Date.fromCalendarDate 1969 Time.Jul 20
|
2022-01-04 22:47:57 +03:00
|
|
|
, checkbox = False
|
2022-01-01 23:50:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-01-14 19:42:14 +03:00
|
|
|
errorsView : List String -> Html msg
|
2022-01-03 19:43:00 +03:00
|
|
|
errorsView errors =
|
|
|
|
case errors of
|
|
|
|
first :: rest ->
|
|
|
|
Html.div []
|
|
|
|
[ Html.ul
|
|
|
|
[ Attr.style "border" "solid red"
|
|
|
|
]
|
|
|
|
(List.map
|
|
|
|
(\error ->
|
|
|
|
Html.li []
|
2022-01-14 19:42:14 +03:00
|
|
|
[ Html.text error
|
2022-01-03 19:43:00 +03:00
|
|
|
]
|
|
|
|
)
|
|
|
|
(first :: rest)
|
|
|
|
)
|
|
|
|
]
|
|
|
|
|
|
|
|
[] ->
|
|
|
|
Html.div [] []
|
|
|
|
|
|
|
|
|
2022-01-14 19:42:14 +03:00
|
|
|
form : User -> Form String User (Html Form.Msg)
|
2022-01-01 23:50:03 +03:00
|
|
|
form user =
|
|
|
|
Form.succeed User
|
2022-01-05 22:21:43 +03:00
|
|
|
|> Form.with
|
2022-01-05 22:23:39 +03:00
|
|
|
(Form.text
|
2022-01-03 18:40:45 +03:00
|
|
|
"first"
|
2022-01-03 19:43:00 +03:00
|
|
|
(\{ toInput, toLabel, errors } ->
|
2022-01-03 18:40:45 +03:00
|
|
|
Html.div []
|
2022-01-03 19:43:00 +03:00
|
|
|
[ errorsView errors
|
2022-01-03 21:07:06 +03:00
|
|
|
, Html.label toLabel
|
2022-01-03 18:40:45 +03:00
|
|
|
[ Html.text "First"
|
|
|
|
]
|
2022-01-03 21:07:06 +03:00
|
|
|
, Html.input toInput []
|
2022-01-03 18:40:45 +03:00
|
|
|
]
|
|
|
|
)
|
2022-01-16 05:28:47 +03:00
|
|
|
|> Form.required "Required"
|
2022-01-17 02:29:06 +03:00
|
|
|
|> Form.withInitialValue (user.first |> Form.Value.string)
|
2022-01-01 23:50:03 +03:00
|
|
|
)
|
2022-01-05 22:21:43 +03:00
|
|
|
|> Form.with
|
2022-01-05 22:23:39 +03:00
|
|
|
(Form.text
|
2022-01-03 18:40:45 +03:00
|
|
|
"last"
|
2022-01-03 19:43:00 +03:00
|
|
|
(\{ toInput, toLabel, errors } ->
|
2022-01-03 18:40:45 +03:00
|
|
|
Html.div []
|
2022-01-03 19:43:00 +03:00
|
|
|
[ errorsView errors
|
2022-01-03 21:07:06 +03:00
|
|
|
, Html.label toLabel
|
2022-01-03 18:40:45 +03:00
|
|
|
[ Html.text "Last"
|
|
|
|
]
|
2022-01-03 21:07:06 +03:00
|
|
|
, Html.input toInput []
|
2022-01-03 18:40:45 +03:00
|
|
|
]
|
|
|
|
)
|
2022-01-16 05:28:47 +03:00
|
|
|
|> Form.required "Required"
|
2022-01-17 02:29:06 +03:00
|
|
|
|> Form.withInitialValue (user.last |> Form.Value.string)
|
2022-01-01 23:50:03 +03:00
|
|
|
)
|
2022-01-05 22:21:43 +03:00
|
|
|
|> Form.with
|
2022-01-05 22:23:39 +03:00
|
|
|
(Form.text
|
2022-01-03 18:40:45 +03:00
|
|
|
"username"
|
2022-01-03 21:07:06 +03:00
|
|
|
(\{ toInput, toLabel, errors } ->
|
|
|
|
Html.div []
|
|
|
|
[ errorsView errors
|
|
|
|
, Html.label toLabel
|
|
|
|
[ Html.text "Username"
|
|
|
|
]
|
|
|
|
, Html.input toInput []
|
|
|
|
]
|
2022-01-03 18:40:45 +03:00
|
|
|
)
|
2022-01-16 05:28:47 +03:00
|
|
|
|> Form.required "Required"
|
2022-01-17 02:29:06 +03:00
|
|
|
|> Form.withInitialValue (user.username |> Form.Value.string)
|
2022-01-02 20:52:04 +03:00
|
|
|
|> Form.withServerValidation
|
|
|
|
(\username ->
|
|
|
|
if username == "asdf" then
|
|
|
|
DataSource.succeed [ "username is taken" ]
|
|
|
|
|
|
|
|
else
|
|
|
|
DataSource.succeed []
|
|
|
|
)
|
2022-01-01 23:50:03 +03:00
|
|
|
)
|
2022-01-05 22:21:43 +03:00
|
|
|
|> Form.with
|
2022-01-05 22:23:39 +03:00
|
|
|
(Form.text
|
2022-01-03 18:40:45 +03:00
|
|
|
"email"
|
2022-01-03 19:43:00 +03:00
|
|
|
(\{ toInput, toLabel, errors } ->
|
2022-01-03 18:40:45 +03:00
|
|
|
Html.div []
|
2022-01-03 19:43:00 +03:00
|
|
|
[ errorsView errors
|
2022-01-03 21:07:06 +03:00
|
|
|
, Html.label toLabel
|
2022-01-03 18:40:45 +03:00
|
|
|
[ Html.text "Email"
|
|
|
|
]
|
2022-01-03 21:07:06 +03:00
|
|
|
, Html.input toInput []
|
2022-01-03 18:40:45 +03:00
|
|
|
]
|
|
|
|
)
|
2022-01-16 05:28:47 +03:00
|
|
|
|> Form.required "Required"
|
2022-01-17 02:29:06 +03:00
|
|
|
|> Form.withInitialValue (user.email |> Form.Value.string)
|
2022-01-01 23:50:03 +03:00
|
|
|
)
|
2022-01-05 22:21:43 +03:00
|
|
|
|> Form.with
|
2022-01-16 05:28:47 +03:00
|
|
|
(Form.date
|
2022-01-03 18:40:45 +03:00
|
|
|
"dob"
|
2022-01-16 05:28:47 +03:00
|
|
|
{ invalid = \_ -> "Invalid date"
|
2022-01-14 19:42:14 +03:00
|
|
|
}
|
2022-01-03 19:43:00 +03:00
|
|
|
(\{ toInput, toLabel, errors } ->
|
2022-01-03 18:40:45 +03:00
|
|
|
Html.div []
|
2022-01-03 19:43:00 +03:00
|
|
|
[ errorsView errors
|
2022-01-03 21:07:06 +03:00
|
|
|
, Html.label toLabel
|
2022-01-03 18:40:45 +03:00
|
|
|
[ Html.text "Date of Birth"
|
|
|
|
]
|
2022-01-03 21:07:06 +03:00
|
|
|
, Html.input toInput []
|
2022-01-03 18:40:45 +03:00
|
|
|
]
|
|
|
|
)
|
2022-01-16 05:28:47 +03:00
|
|
|
|> Form.required "Required"
|
2022-01-17 02:29:06 +03:00
|
|
|
|> Form.withInitialValue (user.birthDay |> Form.Value.date)
|
|
|
|
|> Form.withMin (Date.fromCalendarDate 1900 Time.Jan 1 |> Form.Value.date)
|
|
|
|
|> Form.withMax (Date.fromCalendarDate 2022 Time.Jan 1 |> Form.Value.date)
|
2022-01-01 23:50:03 +03:00
|
|
|
)
|
2022-01-05 22:21:43 +03:00
|
|
|
|> Form.with
|
2022-01-04 22:47:57 +03:00
|
|
|
(Form.checkbox
|
|
|
|
"checkbox"
|
2022-01-04 23:01:11 +03:00
|
|
|
user.checkbox
|
2022-01-04 22:47:57 +03:00
|
|
|
(\{ toInput, toLabel, errors } ->
|
|
|
|
Html.div []
|
|
|
|
[ errorsView errors
|
|
|
|
, Html.label toLabel
|
|
|
|
[ Html.text "Checkbox"
|
|
|
|
]
|
|
|
|
, Html.input toInput []
|
|
|
|
]
|
|
|
|
)
|
|
|
|
)
|
2022-01-03 21:04:42 +03:00
|
|
|
|> Form.append
|
|
|
|
(Form.submit
|
|
|
|
(\{ attrs } ->
|
2022-01-03 21:07:06 +03:00
|
|
|
Html.input attrs []
|
2022-01-03 21:04:42 +03:00
|
|
|
)
|
|
|
|
)
|
2022-01-01 23:50:03 +03:00
|
|
|
|
|
|
|
|
|
|
|
page : Page RouteParams Data
|
|
|
|
page =
|
|
|
|
Page.serverRender
|
|
|
|
{ head = head
|
|
|
|
, data = data
|
|
|
|
}
|
|
|
|
|> Page.buildNoState { view = view }
|
|
|
|
|
|
|
|
|
|
|
|
type alias Data =
|
2022-01-14 01:18:53 +03:00
|
|
|
{ user : Maybe User
|
2022-01-16 02:02:32 +03:00
|
|
|
, errors : Form.Model
|
2022-01-01 23:50:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
data : RouteParams -> Request (DataSource (PageServerResponse Data))
|
|
|
|
data routeParams =
|
|
|
|
Request.oneOf
|
2022-01-16 02:02:32 +03:00
|
|
|
[ Form.submitHandlers
|
|
|
|
(form defaultUser)
|
|
|
|
(\model decoded ->
|
|
|
|
DataSource.succeed
|
|
|
|
{ user = Result.toMaybe decoded
|
|
|
|
, errors = model
|
|
|
|
}
|
|
|
|
)
|
|
|
|
, { user = Nothing
|
|
|
|
, errors = Form.init (form defaultUser)
|
|
|
|
}
|
2022-01-18 03:56:40 +03:00
|
|
|
|> PageServerResponse.render
|
2022-01-01 23:50:03 +03:00
|
|
|
|> DataSource.succeed
|
|
|
|
|> Request.succeed
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
head :
|
|
|
|
StaticPayload Data RouteParams
|
|
|
|
-> List Head.Tag
|
|
|
|
head static =
|
|
|
|
Seo.summary
|
|
|
|
{ canonicalUrlOverride = Nothing
|
|
|
|
, siteName = "elm-pages"
|
|
|
|
, image =
|
|
|
|
{ url = Pages.Url.external "TODO"
|
|
|
|
, alt = "elm-pages logo"
|
|
|
|
, dimensions = Nothing
|
|
|
|
, mimeType = Nothing
|
|
|
|
}
|
|
|
|
, description = "TODO"
|
|
|
|
, locale = Nothing
|
|
|
|
, title = "TODO title" -- metadata.title -- TODO
|
|
|
|
}
|
|
|
|
|> Seo.website
|
|
|
|
|
|
|
|
|
|
|
|
view :
|
|
|
|
Maybe PageUrl
|
|
|
|
-> Shared.Model
|
|
|
|
-> StaticPayload Data RouteParams
|
|
|
|
-> View Msg
|
|
|
|
view maybeUrl sharedModel static =
|
|
|
|
let
|
2022-01-02 21:23:36 +03:00
|
|
|
user : User
|
2022-01-01 23:50:03 +03:00
|
|
|
user =
|
2022-01-02 21:23:36 +03:00
|
|
|
static.data.user
|
2022-01-14 01:18:53 +03:00
|
|
|
|> Maybe.withDefault defaultUser
|
2022-01-01 23:50:03 +03:00
|
|
|
in
|
|
|
|
{ title = "Form Example"
|
|
|
|
, body =
|
2022-01-03 21:07:06 +03:00
|
|
|
[ static.data.user
|
|
|
|
|> Maybe.map
|
2022-01-14 01:18:53 +03:00
|
|
|
(\user_ ->
|
|
|
|
Html.p
|
|
|
|
[ Attr.style "padding" "10px"
|
|
|
|
, Attr.style "background-color" "#a3fba3"
|
|
|
|
]
|
|
|
|
[ Html.text <| "Successfully received user " ++ user_.first ++ " " ++ user_.last
|
|
|
|
]
|
2022-01-03 21:07:06 +03:00
|
|
|
)
|
2022-01-14 01:18:53 +03:00
|
|
|
|> Maybe.withDefault (Html.p [] [])
|
2022-01-03 21:07:06 +03:00
|
|
|
, Html.h1
|
|
|
|
[]
|
|
|
|
[ Html.text <| "Edit profile " ++ user.first ++ " " ++ user.last ]
|
|
|
|
, form user
|
2022-01-16 02:02:32 +03:00
|
|
|
|> Form.toHtml { pageReloadSubmit = True } Html.form static.data.errors
|
2022-01-06 01:09:37 +03:00
|
|
|
|> Html.map (\_ -> ())
|
2022-01-01 23:50:03 +03:00
|
|
|
]
|
|
|
|
}
|