diff --git a/src/js/_enqueues/admin/common.js b/src/js/_enqueues/admin/common.js index 2a7daba0d2dc4..c3d49310e8897 100644 --- a/src/js/_enqueues/admin/common.js +++ b/src/js/_enqueues/admin/common.js @@ -2356,3 +2356,242 @@ $( function( $ ) { // Expose public methods. return pub; })(); + +/** + * Validate the delete-and-reassign users form and surface an accessible + * error summary instead of disabling the submit button. + * + * Disabled buttons can't be discovered by assistive technology, so rather + * than blocking submission we let the form submit, intercept it when content + * decisions are still missing, and present a focusable error summary that + * lists how many decisions remain and links straight to each one. + * + * Shared by both the single-site (wp-admin/users.php) and multisite/network + * (confirm_delete_users() in wp-admin/includes/ms.php) deletion forms. The two + * differ in markup: single site has one content decision per user, multisite + * has one decision per site a user belongs to (several radio groups per + * fieldset), and their reassign dropdowns use different "no selection" values. + * The logic below works per radio group so it covers both. + * + * @since 7.1.0 + */ +(function(){ + const { _n, sprintf } = wp.i18n; + const usersForm = document.querySelector( '.delete-and-reassign-users-form' ); + + // Check if the form exists and contains any radio buttons. + if ( ! usersForm || ! usersForm.querySelector( 'input[type="radio"]' ) ) { + return; + } + + const summaryId = 'delete-users-error-summary'; + + /** + * Whether a reassign dropdown has no user selected. + * + * The "Select a user" placeholder value differs between the forms: the + * single-site dropdown uses an empty string, the multisite one uses the + * wp_dropdown_users() default of '-1'. + * + * @param {HTMLSelectElement} select The reassign dropdown. + * @return {boolean} True when no real user is selected. + */ + function hasNoSelectedUser( select ) { + return '' === select.value || '-1' === select.value; + } + + /** + * Builds a human-readable label for a radio group's decision. + * + * Combines the fieldset legend (the user) with the site context that + * precedes the group on multisite, so each summary entry is identifiable. + * + * @param {HTMLElement} group The radio group (