Really intercept form submit with elm-html

2,376 views
Skip to first unread message

Stéphane Legrand

unread,
Sep 2, 2014, 10:00:13 AM9/2/14
to elm-d...@googlegroups.com
Hello,

I'm currently testing elm-html to make a CRUD interface. When i use the onsubmit event from Html.Events, the related action is effectively done but the form is still submitted. Is there a way to prevent this in order to completely intercept the submit and stop the default action ? In other words, i'm searching the equivalent of the jquery event.preventDefault().

Thanks.
Stéphane.

Trevis

unread,
Jul 1, 2015, 1:37:04 PM7/1/15
to elm-d...@googlegroups.com
Does anyone have some guidance on this? Hitting the same issue currently.

Joost ter Braak

unread,
Jul 1, 2015, 2:52:46 PM7/1/15
to elm-d...@googlegroups.com
I dont really know why you would want to use onSubmit or forms at all. I'm just working with inputs, selects and textareas with the oninput event which updates my model.
But if you really really want onsubmit to do something i think you have to use pure javascript with an Html.Attribute. Make an onsubmit attribute with a function that redirects it to
a more sane eventhandler and return false. Something like:

attribute "onsubmit" "this.dispatchEvent(new Event('change')); return false;"

Then just listen to the change event like normal and handle your stuff. I can't think of any other way other than changing Virtual-Dom itself to return false on occasion.

Op dinsdag 2 september 2014 16:00:13 UTC+2 schreef Stéphane Legrand:

Pete Vilter

unread,
Jul 1, 2015, 4:02:38 PM7/1/15
to elm-d...@googlegroups.com
Use a <button> instead of <input type="submit"/>?

Richard Feldman

unread,
Jul 1, 2015, 4:59:08 PM7/1/15
to elm-d...@googlegroups.com
To answer your question directly, I don't believe elm-html currently has a nice way to accomplish the equivalent of an event.preventDefault() for an onSubmit handler.

However, there may be other ways to get what you want. Can you elaborate on what you're doing with the onSubmit handler?

Stéphane Legrand

unread,
Jul 11, 2015, 11:31:28 AM7/11/15
to elm-d...@googlegroups.com
Thanks for your answers. At that time, i was playing with Elm to see if i could use it for my CRUD interface. And i was simply suprised that it was not possible to prevent the submit. But i agree that a button with a onclick handler can indeed be an other valid way.

Richard Feldman

unread,
Jul 19, 2015, 7:16:31 PM7/19/15
to elm-d...@googlegroups.com
FYI, the latest elm-html release adds support for preventDefault and stopPropagation, so the original intent is totally doable now! :)

Greg Weber

unread,
Sep 8, 2015, 11:41:34 AM9/8/15
to Elm Discuss
Does anyone have an example of capturing form submit and gathering the data?
Right now I still cannot stop the propagation of the form submit, but once that is done I need to gather the form data.
I would like to support both a mouse click on a submit button, and pressing enter to submit, and to be able to gather a group of form fields.

GlenDC

unread,
Sep 8, 2015, 12:44:28 PM9/8/15
to Elm Discuss
I use Html.input for my input fields that listen to the "input" event to update the relevant record.
On top of that I listen to keyboard and also have a button (for me just a div) with a click event, both of these ways send the same action. (so either you press the right button (ENTER) or you press on that div))
That action just does something with the record populated by the input fields.

Hope that makes sense.

You can look around my code of my app at https://github.com/GlenDC/trixel/tree/refactor/src/Trixel but it's quite a lot of code. The input fields and buttons are described in Types/Layout/Input.elm (Warning: it's really not fun code to look at) and that code is for example used in a "new document form" in: Views/Context/MenuPages.elm

Greg Weber

unread,
Sep 8, 2015, 4:44:42 PM9/8/15
to elm-d...@googlegroups.com
Thanks for showing the code.
This is similar to the approach of all the other examples such as http://elm-lang.org/examples/sign-up

None of them actually demonstrate a form submission. When I try to stop a form submission with `onWithOptions`, it does not stop the event from being propogated.

The behaviour of input update and form submission has some fundamental differences.
on input updates as the user types. This is good for some use cases. However, it breaks the web form submission model. As a consequence I have to now also catch the enter keypress at the right spot to simulate what browsers will already do for me. Essentially, I have to re-implement form submission.
Once I figure that out, I have to deal with incrementally updating each field in my model (create an Action for each form field). But there are cases where I don't want to do that; the incremental typing is a throw-away state and I only care about the final submission.
My preference would be instead to instead map a Record to a form and get that back on submission.


--
You received this message because you are subscribed to a topic in the Google Groups "Elm Discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elm-discuss/W3X_m1mE70w/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elm-discuss...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Rehno Lindeque

unread,
Sep 8, 2015, 5:13:49 PM9/8/15
to Elm Discuss
When I was building forms last this was actually a really difficult issue to work around, but I think things have changed now with onWithOptions and preventDefault + stopPropagation (I think both of these might be necessary?) 

Anyway, I just wanted to link https://github.com/evancz/virtual-dom/pull/5 for reference. Also here's some code (unfortunately not very useful, sorry - I'm doing submit action in javascript and hacking around issues like ENTER key presses at the moment. Please let us know a better solution!): https://gist.github.com/rehno-lindeque/74f6f542db029e04b590

Richard Feldman

unread,
Sep 9, 2015, 9:11:11 AM9/9/15
to Elm Discuss
We do this at NoRedInk. Here's the technique that's worked for us:

1. Sync all form inputs to the model as usual (e.g. if there's a text field, add an onKeyUp - or, even better, onInput - handler that uses targetValue to update the model with the string contents of the text field, then render that text field's value with the appropriate model data so it's always in sync with the model)
2. Add an onWithOptions submit handler to the form with { preventDefault = True } so it never causes a location change. (stopPropagation can stay False)
3. Perform validations on the form and display errors if validation failed.
4. If validations passed, then have that onWithOptions handler do one of the following things...
4a. Fire off an Http.post (or whatever you like) to send the model data directly to the server via AJAX.
4b. Update a *completely separate* <form> element with hidden inputs corresponding to the validated model data, then have a port trigger a manual form submission on that element. (From the end user's perspective, it's the same UX as if the original form had been submitted without stopPropagation.) We've used this technique in production and it works on browsers as far back as IE9.

Hope that helps!

Greg Weber

unread,
Sep 9, 2015, 10:53:09 AM9/9/15
to elm-d...@googlegroups.com
In my specific case at the moment I can get by using onKeyUp. However, it would be great if you could put together a sample of your form code at some point.

David Cornu

unread,
Nov 1, 2015, 12:56:25 AM11/1/15
to Elm Discuss
While working through this tutorial, I searched all over for a way to preventDefault() on form submit events and stumbled upon this thread. 

I'm posting my solution here to save others time:

import Html exposing (..)
import Html.Events exposing (..)
import Html.Attributes exposing (type')
import Json.Decode

view address model =
  form
    [ onWithOptions
      "submit"
      { preventDefault = True, stopPropagation = False }
      ( Json.Decode.succeed Nothing )
      (\_ -> Signal.message address { actionType = "SUBMIT", payload = "" })
    ]
    [ button [ type'
"submit" ] [ text "Submit" ] ]

I'm doing some digging to see if there might be a way to pull form data out of the event but this is working pretty well when combined with the "input" event strategy in the tutorial.

Amitai Burstein

unread,
Nov 1, 2015, 3:33:52 AM11/1/15
to Elm Discuss
> I searched all over for a way to preventDefault()

Here's how we are using it - (i.e. action "javascript:void(0);")

flip101

unread,
Nov 1, 2015, 11:27:44 AM11/1/15
to Elm Discuss

Iļja Ketris

unread,
Mar 7, 2016, 1:52:47 PM3/7/16
to Elm Discuss
I wonder if anyone came up with new ideas since this topic started.

There should be a way to not listen for every keystroke and attach a handler to every input field, but just process the whole form once it's submitted.  To me this seems unnecessay complication.
Reply all
Reply to author
Forward
0 new messages