Submit form via external button

I have a form with a “submit” button that is outside the form.

<.form for={@form} phx-change="validate" phx-submit="save">
  ...
</.form>

<button type="button" phx-click={JS.dispatch("submit", to: "form")}>
  Submit
</button>

When I click the button, the form actually submits, as in an http post happens and my push_navigate() is ignored.

What am I doing wrong? Thanks for the help!

That makes sense as it’s just submitting your form as a normal form submit which wouldn’t trigger your "save" genserver callback.

I feel like there must be a way around to do this with JS command but this is a browser-native way to do this. You can have a submit button outside a form with straight HTML like this:

<.form for={@form} id="my-form" phx-change="validate" phx-submit="save">
  ...
</.form>

<button form="my-form">
  Submit
</button>

Untested with LiveView but as far as HTML is concerned, that submit button is “inside” the form so it should work—shouldn’t make any difference to the LiveView js.

4 Likes

That worked perfectly! Thank you! I’m always amazed and embarrassed about how little I know about HTML for being a “web developer”… :joy:

Edit: The button has to be of type=submit, not sure if that’s the default or not, I dunno anything about HTML… :stuck_out_tongue:

1 Like

Yes, type="submit" is the default. That is why you rarely see that but often see <button type="button">, the latter meaning it’s just a “dumb” button. It is what it is :upside_down_face:

I felt the same way when someone first pointed this out to me, and I like to fancy myself as someone who knows HTML quite well :joy: But I still keep learning little things I feel I “should” have known already. The latest was that for videos to auto-play on some devices, you need to include the playsinline attribute. For a good several weeks I was just like, “Guess it’s impossible :person_shrugging:

1 Like