I came upon an interesting problem at work yesterday. A 'search filters' form needed to have two endpoints to which it could submit: one to apply the filters, and another to save the filters as default.
The first implementation was to create a Stimulus controller that intercepted the "save filters" button click, fetched the URL endpoint and the HTTP method via Stimulus
target elements, submitted the form to the given URL, and then reset the form for the other button (which applied filters) which applies the filters.
At first, it seemed to work. At least on the desktop browser. However, during testing, we found problems on iPad Safari. Whenever a user tried to save the filters as default, instead of saving them silently, Safari would show a prompt asking the user to download the filters. Something like this.
create a post using the same form.
Turns out, HTML already has a standardized solution for this problem: the
formaction attribute on a button.
The URL that processes the information submitted by the button. Overrides the
actionattribute of the button's form owner. Does nothing if there is no form owner.
Let's say you have the following form that creates the post:
<form action="/posts" method="post"> <input type="text" name="title" id="post_title"> <textarea name="body" id="post_body"></textarea> <input type="submit" name="commit" value="Create Post"> </form>
And now you want to add another button that generates the preview, you could do this:
<form action="/posts" method="post"> <input type="text" name="title" id="post_title"> <textarea name="body" id="post_body"></textarea> <button type='submit' formaction='/preview'>Preview</button> <input type="submit" name="commit" value="Create Post"> </form>
Pretty cool, right?
Then I ran into another problem.
Override the Parent Form's Method
formmethod attribute, which does just this:
If the button is a submit button, this attribute specifies the HTTP method used to submit the form.
If specified, this attribute overrides the
methodattribute of the button's form owner.
After using these two attributes, the form started working as expected. The prompt on the Safari browser disappeared, too!
P.S. I fixed the bug late on Friday, and the QA still hasn't got a chance to test it yet. So I hope I haven't jinx'ed it by writing this post.
Fingers crossed ;)