Skip to content

Validate hidden inputs#1016

Open
rocket-turtle wants to merge 2 commits into
DavyJonesLocker:mainfrom
rocket-turtle:validate-hidden-inputs
Open

Validate hidden inputs#1016
rocket-turtle wants to merge 2 commits into
DavyJonesLocker:mainfrom
rocket-turtle:validate-hidden-inputs

Conversation

@rocket-turtle
Copy link
Copy Markdown

We use some custom selects which hide the original select. In v23 it was possible to add them back in validate_inputs. After the removal of jQuery in v24 validate_inputs is dead.

This would also be a clean way for this Issue: #616

BTW: I couldnt run the tests but I hope they work :D

@rocket-turtle rocket-turtle force-pushed the validate-hidden-inputs branch from 06bafc3 to b84eb61 Compare May 26, 2026 12:12
@tagliala
Copy link
Copy Markdown
Contributor

Thanks for this PR.

I couldnt run the tests but I hope they work :D

Neither can I: https://www.githubstatus.com/

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an opt-in mechanism to validate form controls that are not visible in the DOM (e.g., native <select> elements hidden by custom widgets or forms hidden via collapse/display rules), addressing the post-jQuery removal gap where validate_inputs was previously used.

Changes:

  • Introduce data-csv-validate-hidden to include hidden elements in validation/binding via a new isValidatable helper.
  • Add QUnit coverage for validating hidden inputs both before and after enabling validations.
  • Update docs/changelog and remove some unused/legacy internal JS exports/APIs.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
test/javascript/public/test/form_builders/validateForm.js Adds QUnit tests covering hidden-input opt-in behavior.
src/utils.js Adds isValidatable and adjusts visibility logic; removes some exports.
src/index.js Uses isValidatable when determining which validated inputs to check on submit.
src/events.js Removes unused default export.
src/core.js Uses isValidatable when enabling/binding inputs; removes unused selector entries.
README.md Documents data-csv-validate-hidden usage and semantics.
CHANGELOG.md Notes the new opt-in feature and related internal export cleanups.
Comments suppressed due to low confidence (1)

src/events.js:37

  • Removing the default export from src/events.js is a breaking change for npm consumers deep-importing from src/ (the package publishes src/**/*.js). If this is intended, it should be treated/documented as a breaking change; otherwise consider keeping a backwards-compatible default export (even if deprecated) that re-exports the named functions.
export const dispatchCustomEvent = (element, eventName, detail) => {
  element.dispatchEvent(new CustomEvent(eventName, {
    bubbles: true,
    detail
  }))
}


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/utils.js
Comment thread src/utils.js
Comment on lines +61 to 71
const isVisible = (element) => {
return Boolean(element.offsetWidth || element.offsetHeight || element.getClientRects().length)
}

export const isValuePresent = (value) => {
return !/^\s*$/.test(value || '')
}

export const removeClass = (element, customClass) => {
if (customClass) {
element.classList.remove(...customClass.split(' '))
}
export const isValidatable = (element) => {
return element.dataset.csvValidateHidden != null || isVisible(element)
}

export default {
addClass,
arrayHasValue,
createElementFromHTML,
getDOMElements,
isFormElement,
isInputElement,
isVisible,
isValuePresent,
removeClass
export const isValuePresent = (value) => {
return !/^\s*$/.test(value || '')
}
Comment thread CHANGELOG.md Outdated
@rocket-turtle rocket-turtle force-pushed the validate-hidden-inputs branch from b84eb61 to 54b0c3b Compare May 27, 2026 13:07
@rocket-turtle
Copy link
Copy Markdown
Author

I updated my commits and removed the parts you changed in https://github.com/DavyJonesLocker/client_side_validations/pull/1017/changes

I also managed to build the new JS and run the test localy


Running QUnit tests

With params: {"autostart":"false"}

..................................................................................................................................

Time: 2943ms, Total: 210, Passed: 210, Failed: 0

@rocket-turtle rocket-turtle force-pushed the validate-hidden-inputs branch from 54b0c3b to 4441b5f Compare May 27, 2026 13:18
@tagliala
Copy link
Copy Markdown
Contributor

@rocket-turtle As per my comment at the issue below, not validating hidden fields is currently a deliberate design choice: #616 (comment)

I also have some concerns about the proposed implementation and naming.

csvValidateHidden does not really mean “validate hidden fields”; it effectively means “always validate this field regardless of visibility”. In practice, this behaves more like a force-validation flag, similarly to how validate: true is already used in other contexts.

To clarify, my goal was never to completely prevent validation of hidden fields at all costs. I am open to supporting this behavior if there is a strong and clear use case for it.

Could you provide a concrete real-world scenario where validating hidden fields on the client side is necessary?

A minimal reproducible example using the playground would help a lot:
https://github.com/tagliala/csv-playground

I guess it is something like adding a javascript select dropbox

@rocket-turtle
Copy link
Copy Markdown
Author

You're right on the naming. What do you think about: data-csv-validate-always, data-csv-force-validate, data-csv-force.

The scenario is a native <select> wrapped by e.g. Tom-Select. (widget hides the original via display:none but writes the value back to it on change)
https://tom-select.js.org/examples

Worth noting this used to be easily doable by overriding ClientSideValidations.selectors.validate_inputs before the jQuery removal. That selector isn't read by the native runtime anymore (the dead entry got dropped earlier in this PR), so this is partly a regression fix - restoring the possibility to validate per field not changing the global do not validate hidden fields choice.

I'm out for two weeks. I'll put together the Tom-Select repro on csv-playground when I'm back, rename to whatever you prefer, or refactor to something other to support this usecase.

@tagliala
Copy link
Copy Markdown
Contributor

Worth noting this used to be easily doable by overriding ClientSideValidations.selectors.validate_inputs before the jQuery removal.

That approach had a subtle bug that made it appear to work correctly only by coincidence.

The problem with overriding validate_inputs

Consider a form with a conditionally revealed field:

┌─────────────────────┐
│ Visible Select    ▼ │
└─────────────────────┘
☐ Checkbox Field

When the checkbox is ticked, a sub-field appears:

┌─────────────────────┐
│ Visible Select    ▼ │
└─────────────────────┘
☑ Checkbox Field
    ☐ Sub-Checkbox Field   ← hidden in DOM, conditionally shown

Broadening validate_inputs to include hidden fields would also cause Sub-Checkbox Field to be validated while it is still hidden — preventing form submission even though the user has no way to interact with it.

In other words: the old workaround didn't correctly distinguish between fields that are always hidden (e.g. a select replaced by a custom widget) and fields that are conditionally hidden (e.g. dependent sub-fields). It happened to work in simple cases, but would silently break forms with conditional field visibility.

Reproduction

A minimal repro is available at:
https://github.com/tagliala/csv-playground/tree/tmp/demonstrate-616

The hidden sub-checkbox fails validation and blocks submission, demonstrating the bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants