- Issue created by @thomas.frobieter
- Assigned to thomas.frobieter
Based on your screenshot I suspect the issue is due to:
1. Whether a field is optional or required, eg. accepting an empty string so it marks as validated
2. If it's filled with text or not, hence the relative size of the icon.Could you test this further and see if it's an actual issue or not Thomas? But I suspect this is a Bootstrap issue rather than Radix if it's not as ideal as it should be
- Status changed to Needs work
6 months ago 12:25pm 19 September 2024 The different sizes validation icons were an Bootstrap SASS misconfiguration on my side, so thats not a problem (they use a calculation for the input fields background-size and a fixed pixel value for the selects - in case somebody else runs into this..).
But the coupon code field (right side in the screenshot) is a thing. Some classes on the input SDC reflect its error state:
<input autocomplete="new-password" data-drupal-selector="edit-sidebar-coupon-redemption-form-code" type="text" id="edit-sidebar-coupon-redemption-form-code--ENE8T-eQybQ" name="sidebar[coupon_redemption][form][code]" value="" size="60" maxlength="128" class="form-textfield error form-control" aria-invalid="true" data-component-id="radix:input" data-once="coupon-redemption-code">
But 'aria-invalid' should be false.
The CSS selector for the invalid marker is:
.was-validated .form-control:invalid, .form-control.is-invalid {}
So I think 'is-invalid' should be set on the input.
But this won't work either, because:
.was-validated .form-control:valid, .form-control.is-valid
(green checkmark)
overrides the .is-invalid selector.
As of the docs, this is due to this:
- To reset the appearance of the form (for instance, in the case of dynamic form submissions using Ajax), remove the .was-validated class from the
again after submission. - As a fallback, .is-invalid and .is-valid classes may be used instead of the pseudo-classes for server-side validation. They do not require a .was-validated parent class.
https://getbootstrap.com/docs/5.3/forms/validation/#how-it-works
The coupon code submission triggers an AJAX update of the form, so as I understand it, the "was-validated" class should be removed then? Or should it be removed in general, as server-side validation is the default in Drupal? Of course "was-validated" is set by the BS JS, so "needs-validation" should be removed in case of server-side validation.
Without the was-validated class on the form and with the is-invalid class on the input, everything seems fine.
- To reset the appearance of the form (for instance, in the case of dynamic form submissions using Ajax), remove the .was-validated class from the
Another example on the user edit form.
When switching to the classes mentioned in #6 'is-invalid' / 'is-valid' on the input elements, it works well (this time on the user edit form).
With 'needs-validation' class on form, without 'is-valid' / 'is-invalid' class on input:
Without 'needs-validation' class on form, but with 'is-valid' / 'is-invalid' class on input:
My conclusion is: In case of the user edit form, the BS client side validation passes, but the server side validation fails. In this case the 'was-validated' class needs to be removed, and the input classes 'is-valid' / 'is-invalid' needs to be set.
Maybe this just needs to be removed from form.theme:
function validateForm(array &$form, FormStateInterface $form_state) { if (!empty($form_state->getErrors())) { $form['#attributes']['class'][] = 'was-validated'; } }
And the 'was-validated' class should only set using JS, like described here:
(() => { 'use strict' // Fetch all the forms we want to apply custom Bootstrap validation styles to const forms = document.querySelectorAll('.needs-validation') // Loop over them and prevent submission Array.from(forms).forEach(form => { form.addEventListener('submit', event => { if (!form.checkValidity()) { event.preventDefault() event.stopPropagation() } form.classList.add('was-validated') }, false) }) })()
Also note hat .invalid-feedback never shows up without the 'is-valid' / 'is-invalid' classes (my test case on this was, to try to change your user mail address to an mail address which is already assigned to another account => "The email address bar@foo.com is already taken.").
Also on AJAX forms, the 'was-validated' class should be removed after submission:
"To reset the appearance of the form (for instance, in the case of dynamic form submissions using Ajax), remove the .was-validated class from the
again after submission." (See docs).I now used a dirty workarounded to quickfix this, by removing "needs-validtion" from the form entirely and and set the 'is-invalid' class on the input_classes using:
attributes.hasClass('error') ? 'is-invalid'
- Issue was unassigned.
- Status changed to Needs review
3 months ago 10:23pm 13 December 2024 - 🇺🇸United States danchadwick Boston
Agree with everything Thomas said. Bumping to Major since server validation errors are shown with green checkmarks, making it very difficult for the user to see which field is invalid.
First, yes, the bootstrap classes are unfortunate because
.is-invalid
cannot override:valid
. Therefore,.was-validated
must not be added by the server. Second, adding.is_invalid
wherever a form element has theerror
at least shows the errant field. We lose the feature of having green checkmarks.I did try using javascript to manually set the custom validation (
setCustomValidity()
) for fields in response to the error. However, this prevents the form from being submitted and even prevents the submit handler from being executed.The attached patch does what Thomas suggested.
- 🇺🇸United States danchadwick Boston
Additional thought. To keep the green checkmark functionality, the "is-invalid" or "is-valid" class setting could be moved to preprocess functions, setting one or the other when the element had been validated (
$variables['element']['#validated]
.Maybe the maintainers can indicate a preferred direction.
- 🇺🇸United States danchadwick Boston
Here's a re-roll to be applied after the issue remove the spaceless filter tags is committed.
-
danchadwick →
committed 6f23af58 on 6.0.x
Issue #3473353 by danchadwick, thomas.frobieter: Server-side form...
-
danchadwick →
committed 6f23af58 on 6.0.x
Automatically closed - issue fixed for 2 weeks with no activity.