HTML5 validation on required but triggerly hidden field.
Nobody has claimed this yet.
- Dominant language
- PHP
- Stars
- 1.5k
- Forks
- 246
- Avg merge
- 19h 2m
- Merged PRs (30d)
- 7
Description
Winter CMS Build
1.2.9
PHP Version
8.3
Database engine
MySQL/MariaDB
Plugins installed
No response
Issue description
Since version 1.2.9, HTML5 validation is enabled for all form fields. I don't know why, but this wasn't the case in previous versions (tested on versions 1.2.6 and 1.2.7; I can't verify for 1.2.8 but I think it was the same behavior).
Unfortunately, the browser now prevents form submission when a show/hide trigger makes a required field invisible, without displaying an error message, because the browser cannot focus on an invisible field.
Steps to replicate
Create a Model with
use \Winter\Storm\Database\Traits\Validation;
/**
* @var array Validation rules
*/
public $rules = [
'bindings_qty' => 'required|integer|min:1',
];
public function beforeValidate()
{
if (!$this->bindings) unset($this->rules['bindings_qty'])
}
and in his fields.yaml, put this:
fields:
bindings:
label: Bindings
type: switch
bindings_qty:
label: Bindings quantity
type: number
trigger:
action: show
field: bindings
condition: checked
When creating or updating a record from his form, make sure there is no value inside bindings_qty et then uncheck bindings.
Workaround
This JS file added to my FormController do the trick.
/*
* Fix for WinterCMS 1.2.9+
* Intercepts HTML5 validation to ignore fields hidden by triggers
* and restores the behavior from before 1.2.9
*
* This script restores the old behavior only for hidden fields.
* They will not be validated by HTML5, even if they have the 'required' attribute.
*/
+function ($) { "use strict";
/**
* Checks if an element is visible (not hidden by display:none or the hide class)
*/
function isElementVisible(element) {
var $el = $(element);
// Check if the element or one of its parents is hidden
if ($el.hasClass('hide') || $el.is(':hidden')) {
return false;
}
// Check parents
var $parent = $el.closest('[data-trigger]');
if ($parent.length && $parent.hasClass('hide')) {
return false;
}
return true;
}
/**
* Overrides checkValidity() to ignore hidden fields
*/
if (typeof HTMLFormElement !== 'undefined' && HTMLFormElement.prototype.checkValidity) {
var originalCheckValidity = HTMLFormElement.prototype.checkValidity;
HTMLFormElement.prototype.checkValidity = function() {
// Call the original validation
var isValid = originalCheckValidity.call(this);
// If the form is invalid, check if this is because of a hidden field
if (!isValid) {
var invalidFields = this.querySelectorAll(':invalid');
var hasVisibleInvalid = false;
for (var i = 0; i < invalidFields.length; i++) {
if (isElementVisible(invalidFields[i])) {
hasVisibleInvalid = true;
break;
}
}
// If all invalid fields are hidden, treat the form as valid
if (!hasVisibleInvalid) {
return true;
}
}
return isValid;
};
}
}(window.jQuery);
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Validation trait, the fields.yaml trigger configuration, and the FormController JavaScript workaround described in the issue. Reproduce the required hidden-field case on Winter CMS 1.2.9, then trace the HTML5 validation and trigger behavior. Done means hidden required fields no longer block submission, while visible invalid fields still produce normal validation feedback.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, php
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100