wintercms / wintercms/winter

HTML5 validation on required but triggerly hidden field.

Open
#1,442 0 comments 0 reactions 0 assignees View on GitHub

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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.