x-govuk/govuk-form-builder

govuk_submit should output a button instead of an input

Closed this issue · 5 comments

Currently, the formbuilder method govuk_submit outputs a button using <input type="submit">.

However, this has a bug which is that if you click the button on its top edge, the button will animate as if it has been clicked, but will not do anything. Users have been observed stumbling across this in research.

The fix is to switch to using a<button> element instead – which is also what the GOV.UK Design System recommends.

We could either change govuk_submit to output a button element, or arguably we could remove this method from the formbuilder altogether, as it doesn’t need to bind to any form variables, and instead add a govuk_button helper to the govuk-components Gem and use a component there?

In addition, the button should always have data-module="button" added to it, to support some additional javascript for preventing double clicks and enabling the spacebar to be used for links styled as buttons.

Previously reported here: #203

Thanks @frankieroberto - I'm keen for this to remain in the form builder as that's where most people would expect to find it. As it's actually causing problems that affect users it'll definitely be resolved - I'm not totally sure of the best way yet, but it'll probably be either:

  • a #govuk_submit_button helper on the builder that renders a button
  • an argument (with corresponding config to set the default) that can be supplied to the existing #govuk_submit, which toggles between input and button

I'd assume that if we're rendering a <button> element we'd want to be able to provide its contents with a block of HTML in addition to a string, and #govuk_submit already uses its block to wrap itself in a button group, so maybe the former would make more sense.

I had a really quick play with the idea and think it might be the way forward.

Adding a button: param to #govuk_submit that defaults to the configuration's default setting - true to always render buttons by default and false to use inputs.

This allows buttons to be configured by the developer if one or the other is needed for a odd circumstance.

Also, the button arg could take a proc (as seen elsewhere in the library), that would allow the contents of the <button> element to be set with any arbitrary HTML.

Unless I've missed something here it feels like a sensible approach that'll work for most people. I'm hesitant to just switch over from input to button en masse as it'll mean people will need to update their tests.

Happy to keep it in the formbuilder, although I think it’d be good to make it available outside of a formbuilder as a global helper too, given that it doesn’t need to bind to the form model.

I don't think we have any reason to also support the <input type="submit">, especially with that bug.

Given how prevalent form buttons are, it might be sensible to think through how to enable users to switch to the button in the least painful way.

Options could be:

  1. make govuk_submit output a button, but do this in a major version release as it might break some existing tests which expect an input. However this might require the least downstream changes.
  2. create a new govuk_button or govuk_submit_button method and/or helper.
  3. mark govuk_submit as deprecated for a version.

Agree with supporting block content as well as a string. One of the advantages of the <button> element is that it can support additional markup (although it's rarely needed).

We should also make sure that both the button and the link-styled-as-button support both the prevent-double-click option and start-button option – and that both include the data-module="govuk-button" attribute.

If people are using the capybara method click_button in their tests, then that shouldn’t require any code changes, as that already supports both <input type="button"> and <button>.