Opened 7 years ago
Last modified 3 weeks ago
#47505 accepted defect (bug)
Create a comprehensive input validation API for WordPress editor and administration interface
| Reported by: | greatislander | Owned by: | audrasjb |
|---|---|---|---|
| Priority: | normal | Milestone: | Future Release |
| Component: | Administration | Version: | |
| Severity: | normal | Keywords: | needs-design input-validation form-controls has-patch has-unit-tests |
| Cc: | Focuses: | ui, accessibility |
Description
Currently, WordPress lacks a comprehensive API for validating form input and alerting users to errors or missing fields. One example of how this can cause problems was captured by @conner_bw in #47018 -- failing to fill in the required ‘Name’ field when creating a new taxonomy term highlights the field in red but provides no textual message indicating that a required field is missing. As noted by @afercia:
there are at least two WCAG success criteria (1 is level A, the other one is level AA) that requires a clear identification of the item in error and clear suggestions for correction.
The lack of input validation mechanisms has also been noted as a shortcoming in Gutenberg (see tweet from @spacedmonkey about this).
In the Slack discussion of #47018, the Accessibility team agreed that the broader goal of researching and planning a comprehensive form validation API would be a valuable project that would benefit all users. This ticket should serve as a starting point for that exploration process. One example of how this could work shared during the discussion was something along the lines of Tenon’s React-based form validation library: https://www.tenon-ui.info/forms-full-demo
Two use cases that this API should cover:
- Required input is missing
- Required input is not the expected type
To be continued!
Change History (15)
#1
@
7 years ago
- Summary Create a comprehensive form validation API for WordPress editor and administration interface → Create a comprehensive input validation API for WordPress editor and administration interface
This ticket was mentioned in Slack in #design by spacedmonkey. View the logs.
7 years ago
#5
@
7 years ago
Related: #47595 for the post comments form in the front end. Which leads us to: should the proposed API be used also for forms in the front end?
#6
@
7 years ago
Relevant standards:
WCAG Success Criterion 3.3.1 Error Identification
https://www.w3.org/TR/WCAG21/#error-identification
If an input error is automatically detected, the item that is in error is identified and the error is described to the user in text.
WCAG Success Criterion 3.3.3 Error Suggestion
https://www.w3.org/TR/WCAG21/#error-suggestion
If an input error is automatically detected and suggestions for correction are known, then the suggestions are provided to the user, unless it would jeopardize the security or purpose of the content.
#7
@
7 years ago
- Version trunk
Note: removing version "trunk", as it's generally used to indicate regressions in trunk.
This ticket was mentioned in Slack in #accessibility by afercia. View the logs.
7 years ago
This ticket was mentioned in Slack in #accessibility by afercia. View the logs.
7 years ago
This ticket was mentioned in Slack in #accessibility by afercia. View the logs.
7 years ago
This ticket was mentioned in Slack in #accessibility by audrasjb. View the logs.
7 years ago
#13
@
7 years ago
- Milestone Awaiting Review → Future Release
Moving to Future release as it will need some early work during the next release process.
This ticket was mentioned in Slack in #accessibility by greatislander. View the logs.
7 years ago
This ticket was mentioned in PR #13664 on WordPress/wordpress-develop by @faisalahammad.
3 weeks ago
#15
- Keywords has-patch has-unit-tests added; needs-patch needs-unit-tests removed
WordPress has no shared way for an admin form to validate its input and tell the user which field failed and why. The pieces that exist are all partial. add_settings_error() and settings_errors() print global notices with no link to a specific field, validateForm() only adds the form-invalid class and no text, and the accessible field level errors in core are per feature code in the nav menu and the customizer. The example in the ticket, the taxonomy Name field turning red with no message, is the clearest case of the gap.
This adds a small field level error contract for admin screens and proves it in the taxonomy add and edit forms. wp_register_form_error() records an error against a field id during the request, wp_get_form_errors() and wp_get_form_error() read them back, wp_render_form_error() prints the inline message, and wp_save_form_errors() carries the errors across a redirect in a short lived per user transient. The rendered element is a paragraph with the field id plus "-error" as its id, the form-error class and role="alert", so it can be associated with the input through aria-describedby. validateForm() now also sets aria-invalid on the invalid input and appends a registered error element to aria-describedby, without changing its signature or its return value.
In the taxonomy screens the empty term name case now registers a field error on the name input and redirects with a form-errors flag, keeping the existing generic message for backwards compatibility. The AJAX path in tags.js attaches the same error element before it calls validateForm(), so both submit paths report the field the same way. Errors survive the redirect through the transient rather than through the URL, so no message text is placed in the query string.
Scope: this patch covers a server side field error API for classic admin screens, the matching validateForm() behavior, and one real integration in the taxonomy add and edit screens on both the classic and AJAX paths. It does not cover the block editor or the Gutenberg packages, validation of an input type other than an empty required value, or a decision about where a wider API should live. The ticket is still Future Release with the needs-design keyword, so this is intentionally a small slice that can be reviewed on its own and does not close the ticket.
Testing
The change was verified with the host PHPUnit run, since the Docker environment is not usable here. Point DB_HOST at a local test database, run the tests, then restore it.
vendor/bin/phpunit -c phpunit.xml.dist tests/phpunit/tests/admin/formValidation.php
vendor/bin/phpunit -c phpunit.xml.dist --group ajax tests/phpunit/tests/ajax/wpAjaxAddTag.php
vendor/bin/phpunit -c phpunit.xml.dist tests/phpunit/tests/taxonomy/wpInsertTerm.php
That reports 6 tests and 14 assertions for the new API tests, 5 tests for the AJAX add tag case and 37 tests for wp_insert_term(), all passing. The full suite shows only the one pre-existing failure in the script modules test. The public functions were also checked with a deliberately wrong expectation to confirm the assertions actually run and fail when the code under test is changed. PHPCS with the core ruleset is clean on the changed files.
The JavaScript is covered by QUnit in tests/qunit/wp-admin/js/form-validation.js, which loads the built common.js. Run grunt copy:admin-js after editing the source, then open tests/qunit/index.html. The run reports 590 passing of 605, with the 15 failures being the pre-existing media models cases. The three new tests pass.
To check it in a browser, open the taxonomy screen for a taxonomy with a name field, submit the add term form with the name empty, and confirm the inline message appears next to the field, the input is marked aria-invalid="true", and the message is the value of its aria-describedby. Repeat with the AJAX add path. This changes only the message color next to a field, so the visual check is limited to the new message not breaking the field layout in an RTL locale and in both admin color schemes.
Use of AI Tools
AI assistance: Yes
Tool(s): ZCode
Model(s): GLM 5.3
Used for: Investigating the existing validation code, drafting and iterating on the implementation and tests, and drafting this description. The final change was reviewed and tested before submission.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
I have a somewhat related ticket on the gutenberg repo - https://github.com/WordPress/gutenberg/issues/14644