forms icon indicating copy to clipboard operation
forms copied to clipboard

Button: Confusing way to make Non-default Buttons in Form

Open jakubboucek opened this issue 6 months ago • 2 comments

When I have more Buttons in Form, most cases is: only one button is understood as the default - that's what User expecting.

We have a Form where is one Button Save which is for store final form state and it's visually distinct - it's Default Button. There are also other buttons in the form that do not save the form, but make modifications to it (add or remove fields) - these are Non-Default Buttons.

Image

Form code is here:

https://github.com/barcampkolin/barcampkolin-web/blob/beb782b79d456ff268b173890a948e5d8b79e542/app/Components/Enumerator/EnumeratorFormControl.php#L62-L86

User expecting when hits Enter key at some input field, the Form is submitted and stored. But as HTML is defined when user hits Enter the nearest Submit Button is invoked – in this form it causes to unexpected deleting of part of Form.

Form modifications are performed on server-side, that's mean the form submission function after explicit pressing the Buttons must be preserved – we want only make it non-default.

Non-default Button can be in HTML defined by modify the type attribute: type="button" instead of type="submit".

What Nette currently providing

Nette\Form provides few ways to make Button in Form:

addButton()

$form->addButton(...)

// <button type="button">

Unusable – this make only visually Button, but on server-side is no submit handlers like isSubmittedBy(), etc.

addSubmit()

$form->addSubmit(...)

// <input type="submit">

This makes Button with "Default Button" behavior.

->renderAsButton()

$form->addSubmit(...)->renderAsButton()

// <button type="submit">

Only changes HTML tag from <input> to <button>, but no change type attribute. This makes Button with "Default Button" behavior.

How to make Button non-default with Nette?

Only way to make Button non-default is confusing:

$form->addSubmit(...)->setHtmlAttribute('type', 'button')

// <input type="button">

This makes expected behavior:

  • when user explicitly hit Button, form is submitted,
  • when user hit Enter key in form, this Button is not invoked.

It works and we use it (barcampkolin/barcampkolin-web#39).

Problem

Using $form->addSubmit(...)->setHtmlAttribute('type', 'button') is too confusing, rspt. the reason for using the setHtmlAttribute() method is not sufficiently clear and may give the impression that it is a forgotten fragment of code that is redundant. Moreover, the whole situation is further burdened by the existence of the renderAsButton() method, which makes understanding the whole issue even more difficult.

Proposal

Make new method SubmitButton::setAsNonDefault() which is only changes type attribute to button. maybe setAsNonDefault name is insufficiently explanatory meaning, maybe it should be named as setNoImplicitSubmit().

I can submit a Pull Request, but first let me know what you think of my ideas.

jakubboucek avatar Jun 04 '25 09:06 jakubboucek

Do I understand correctly that you are missing submit handlers like isSubmittedBy() for type="button"? And what would you need them for?

dg avatar Jun 05 '25 09:06 dg

ping @jakubboucek

dg avatar Jun 18 '25 18:06 dg