Skip to content

Commit

Permalink
Add SetField Msg
Browse files Browse the repository at this point in the history
  • Loading branch information
MattiaVerticchio committed Oct 8, 2024
1 parent 5654b80 commit 5271a83
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 12 deletions.
48 changes: 42 additions & 6 deletions examples/end-to-end/app/Route/Form.elm
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module Route.Form exposing (ActionData, Data, Model, Msg, route)

import BackendTask exposing (BackendTask)
import Date exposing (Date)
import Effect exposing (Effect)
import ErrorPage exposing (ErrorPage)
import FatalError exposing (FatalError)
import Form
Expand All @@ -12,6 +13,7 @@ import Form.Validation as Validation
import Head
import Html exposing (Html)
import Html.Attributes as Attr
import Html.Events
import Html.Styled
import Pages.Form
import PagesMsg exposing (PagesMsg)
Expand All @@ -27,8 +29,8 @@ type alias Model =
{}


type alias Msg =
()
type Msg
= FirstNameUpdated String


type alias RouteParams =
Expand Down Expand Up @@ -118,7 +120,7 @@ form =
, fieldView "Price" username
, fieldView "Image" email
, fieldView "Image" dob
, Html.button []
, Html.button [ Attr.id "update" ]
[ Html.text
(if formState.submitting then
"Updating..."
Expand Down Expand Up @@ -170,14 +172,19 @@ form =
|> Form.field "checkbox" Field.checkbox


route : StatelessRoute RouteParams Data ActionData
route : RouteBuilder.StatefulRoute RouteParams Data ActionData Model Msg
route =
RouteBuilder.serverRender
{ head = head
, data = data
, action = action
}
|> RouteBuilder.buildNoState { view = view }
|> RouteBuilder.buildWithLocalState
{ init = init
, update = update
, subscriptions = \_ _ _ _ -> Sub.none
, view = view
}


type alias Data =
Expand Down Expand Up @@ -217,11 +224,32 @@ head static =
[]


init : App Data ActionData RouteParams -> Shared.Model -> ( Model, Effect msg )
init _ _ =
( {}, Effect.none )


update :
App Data ActionData RouteParams
-> Shared.Model
-> Msg
-> Model
-> ( Model, Effect msg )
update _ _ msg model =
case msg of
FirstNameUpdated new ->
( model
, Effect.SetField
{ formId = "user-form", name = "first", value = new }
)


view :
App Data ActionData RouteParams
-> Shared.Model
-> Model
-> View (PagesMsg Msg)
view app shared =
view app shared _ =
let
user : User
user =
Expand Down Expand Up @@ -257,6 +285,14 @@ view app shared =
|> Form.withServerResponse (app.action |> Maybe.map .formResponse)
)
app
, Html.button
[ Html.Events.onClick <|
PagesMsg.fromMsg <|
FirstNameUpdated "Jim"
, Attr.style "width" "100%"
, Attr.id "fill-jim"
]
[ Html.text "Set first name to Jim" ]
]
|> List.map Html.Styled.fromUnstyled
}
8 changes: 7 additions & 1 deletion examples/end-to-end/cypress/e2e/form-submissions.cy.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
context("dev server with base path", () => {
it("fills name field with 'Jim' when clicking a new button", () => {
cy.visit("/form");
cy.get("input[name=first]").should("have.value", "Jane");
cy.get("button#fill-jim").click();
cy.get("input[name=first]").should("have.value", "Jim");
});
it("submits a form to receive ActionData", () => {
cy.visit("/form");
cy.get("input[name=first]").clear().type("John");
cy.get("input[name=last]").clear().type("Asdf");
cy.get("button").click();
cy.get("button#update").click();
cy.contains("Successfully received user John Asdf");
});
it.skip("logs in and out", () => {
Expand Down
52 changes: 47 additions & 5 deletions src/Pages/Internal/Platform.elm
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import Bytes exposing (Bytes)
import Bytes.Decode
import Dict exposing (Dict)
import Form
import Form.Validation exposing (FieldStatus(..))
import Html exposing (Html)
import Html.Attributes as Attr
import Http
Expand Down Expand Up @@ -310,7 +311,7 @@ type Msg userMsg pageData actionData sharedData errorPage
| UrlChanged Url
-- TODO rename to PagesMsg
| UserMsg (PagesMsg userMsg)
--| SetField { formId : String, name : String, value : String }
| SetField { formId : String, name : String, value : String }
| FormMsg (Form.Msg (Msg userMsg pageData actionData sharedData errorPage))
| UpdateCacheAndUrlNew Bool Url (Maybe userMsg) (Result Http.Error ( Url, ResponseSketch pageData actionData sharedData ))
| FetcherComplete Bool String Int (Result Http.Error ( Maybe userMsg, ActionDataOrRedirect actionData ))
Expand Down Expand Up @@ -583,6 +584,47 @@ update config appMsg model =
Pages.Internal.Msg.NoOp ->
( model, NoEffect )

SetField info ->
let
newForm : Form.FormState
newForm =
case Dict.get info.formId model.pageFormState of
Nothing ->
{ fields =
Dict.singleton info.name
{ value = info.value
, status = NotVisited
}
, submitAttempted = False
}

Just oldForm ->
let
newField : Form.FieldState
newField =
case Dict.get info.name oldForm.fields of
Nothing ->
{ value = info.value
, status = NotVisited
}

Just oldField ->
{ value = info.value
, status = oldField.status
}
in
{ fields =
Dict.insert info.name newField oldForm.fields
, submitAttempted = oldForm.submitAttempted
}
in
( { model
| pageFormState =
Dict.insert info.formId newForm model.pageFormState
}
, NoEffect
)

UpdateCacheAndUrlNew scrollToTopWhenDone urlWithoutRedirectResolution maybeUserMsg updateResult ->
-- TODO remove all fetchers that are in the state `FetcherReloading` here -- I think that's the right logic?
case
Expand Down Expand Up @@ -1007,10 +1049,10 @@ perform config model effect =
, fromPageMsg = Pages.Internal.Msg.UserMsg >> UserMsg
, key = key
, setField =
\_ ->
--Task.succeed (SetField info) |> Task.perform identity
-- TODO
Cmd.none
\info ->
SetField info
|> Task.succeed
|> Task.perform identity
}

Nothing ->
Expand Down

0 comments on commit 5271a83

Please sign in to comment.