Checkbox form does not submit on Safari and Mobile Chrome (using requestSubmit)

Hi all,
I have a single checkbox form that I’m trying to submit, which will then call the Update action of my controller, which in turn will call a Turbostream.
It’s been working fine — except, as I discovered recently after deploying, in Safari desktop, Safari mobile, and (strangely enough) Chrome on my iPad. They do DO NOT submit the form when the checkbox is changed.

Here is the simple code (which also calls an unrelated Stimulus action):

<%= form.check_box :completed, onchange: "this.form.requestSubmit()", data:{ action: "change->count-checked-checkboxes#count}, class:”blah”, style:”blah” %>

I came across a bunch of posts here (some from as far back as Dec 20), which talked about using requestSubmit (as I’m using), but that it didn’t support Safari. A workaround was using “ form-request-submit-polyfill ”, and that workaround was in fact incorporated in Turbo 7.1 in mid-November 2021.

MY QUESTIONS

  1. I started my app about a week after ‘ form-request-submit-polyfill ’ was added to Turbo 7.1, and now I’m wondering if I don’t have the latest updates. My app is on Rails 6.1, and used the ‘Hotwire-rails’ gem (since deprecated) to get all the Hotwire libraries. I updated that gem recently, and that also upgraded a ‘turbo-rails’ dependency to 1.0.1 (was 0.5.12). Is there anything else I need to upgrade to get the polypill solution that was built into Turbo 7.1, or is that something limited to Rails 7?

  2. As an alternative, I’m not sure how to implement ‘ form-request-submit-polyfill ’ in my existing Rails 6.1 app. This issue was the first time I ever heard of a “polyfill” and while I found a lot of people talking about it, I couldn’t find any examples of how to actually implement it.

Any guidance appreciated, thanks very much!

I ran into this bug a few weeks ago. I thought I needed the “requestSubmit” polyfill for safari, then I noticed that stimulus.js already includes it, I couldn’t figure out why it still wasn’t working on safari, then I was finally able to get it working by passing a reference to the submit button into the requestSubmit function.

My particular stimulus controller was for auto-submitting a form on file selected, but the important part is here:

const submitButton = this.element.querySelector('[type="submit"]')


this.element.addEventListener('change', () => {
      this.element.requestSubmit(submitButton)
    })

this.element in the code above is a <form> element.

Passing a reference to the input button is supposed to be optional, but it’s the only thing which made it work for me on safari.

Good luck

yanshiyason, thanks very much for that. I haven’t solved the problem, but your answer helped me narrow it down, I think.

Based on your answer, I re-constructed my form to include a hidden Submit button… The form’s Checkbox HTML references a Stimulus action on change, and that Stimulus action targets the form and its submit button, and uses parent_form.requestSubmit(submitButton) to submit the form.

It works in Chrome and Firefox, but again, still fails in Safari desktop, Safari iOS and Chrome iOS.

So I think the problem might be that my Turbo version is still at 7.0.1 not 7.1 which is when the request-submit-polyfill was added. In my node-modules>@hotwired>turbo folder, the version for @hotwired/turbo is 7.0.1, and I can’t find any other reference to a 7.1 for Turbo in my app. So maybe that is indeed the hitch.

All my bundles are updated for this Rails 6.1 app, though, so I guess that’s the next direction of my research…

Thanks much for your help…

FYI for anyone that runs into this issue with Turbo 7.1 installed, here’s my code…

THE FORM

        <%= form_for @task do |form| %>
          <%= form.check_box :completed, data:{ action: "change->count-checked-checkboxes#change change->count-checked-checkboxes#submitCheckboxOnClick"}, class:"ml-1 md:ml-4 checkbox", style:"width: 30px; height: 30px;" %>
          <%= form.submit class:"hidden" %>
        <% end %>

THE STIMULUS ACTION

  submitCheckboxOnClick(event) {
    const parent_form = event.target.parentElement;
    const submitButton = parent_form.querySelector('[type="submit"]')
    parent_form.requestSubmit(submitButton)
}

Well, I tried a different approach using Turbo’s 'Navigator class, as described in this thread below, and it worked. All browsers are behaving properly. Whew.

https://discuss.hotwired.dev/t/triggering-turbo-frame-with-js/1622/50

Happy to know you fixed it! Cheers :beers: