elm

Can elm form submission go to a relative URL path?


From my understanding (which could be wrong), the Elm way of doing HTML form submission is to send a Msg via the onClick event of the submit button, and then do an HTTP request to the server. The only problem with that, is that I need to hard-code the full URL to make the request to, which makes switching between localhost and prod-ready code more challenging.

I basically want to get the same ability as standard HTML forms have to make the request to a relative path. e.g.

Html.form [ method "POST", action "/my-api", target "my-api" ] [...]

The issue with using this code is that it's designed for classic HTML serving websites, and will essentially refresh the page (even if I code my server just to redirect back), which isn't really ideal/necessary for an Elm SPA.

There are some hacky solutions I could do to make either of these work (i.e. sed replace all 'localhost' strings in my deployment script. Or using URL query params to preserve Elm model state through redirect to server and then back to the same page of the SPA). But I'm wondering if I've missed or haven't thought of something that will make this cleaner?


Solution

  • I would say the most common way has not changed much since this answer.

    To submit a form in Elm (and not navigate away from the page) I would add an onSubmit event handler to the form element.
    That way, the "form submission" will be triggered by pressing the submit button, or by pressing "Enter" in a single-line text input.

    Html.form [ Html.Events.onSubmit Submit ]
        [ Html.input
            [ Html.Attributes.type_ "text"
            , Html.Attributes.value model.name
            , Html.Events.onInput InputName
            ]
            []
        , Html.button [ Html.Attributes.type_ "submit" ] [ Html.text "submit" ]
        ]
    

    Then you can use for instance Http.post to send the form data to your server.
    The post request body could be formatted as form data (like the plain html form), or as JSON, simple text, or a binary format.

    For a full code example, see https://ellie-app.com/nn4T2npMLMka1