Make WordPress Core

Changeset 60700


Ignore:
Timestamp:
09/01/2025 09:20:13 PM (3 months ago)
Author:
joedolson
Message:

Accessibility: Feedback & focus on deleting terms via AJAX.

When deleting a term using AJAX, notify screen reader users of the deletion using wp.a11y.speak(), set the active row to be unfocusable, then explicitly set new focus after the deletion is completed.

Props jeremyfelt, afercia, wido, nikunj8866, SirLouen, pmbaldha, joedolson.
Fixes #47101.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/js/_enqueues/admin/tags.js

    r59960 r60700  
    3131        if ( r ) {
    3232            data = t.attr('href').replace(/[^?]*\?/, '').replace(/action=delete/, 'action=delete-tag');
     33
     34            tr.children().css('backgroundColor', '#faafaa');
     35
     36            // Disable pointer events and all form controls/links in the row
     37            tr.css('pointer-events', 'none');
     38            tr.find(':input, a').prop('disabled', true).attr('tabindex', -1);
    3339
    3440            /**
     
    4147             */
    4248            $.post(ajaxurl, data, function(r){
     49                var message;
    4350                if ( '1' == r ) {
    4451                    $('#ajax-response').empty();
     52                    let nextFocus = tr.next( 'tr' ).find( 'a.row-title' );
     53                    let prevFocus = tr.prev( 'tr' ).find( 'a.row-title' );
     54                    // If there is neither a next row or a previous row, focus the tag input field.
     55                    if ( nextFocus.length < 1 && prevFocus.length < 1 ) {
     56                        nextFocus = $( '#tag-name' ).trigger( 'focus' );
     57                    } else {
     58                        if ( nextFocus.length < 1 ) {
     59                            nextFocus = prevFocus;
     60                        }
     61                    }
     62
    4563                    tr.fadeOut('normal', function(){ tr.remove(); });
    4664
     
    5472                    $('select#parent option[value="' + data.match(/tag_ID=(\d+)/)[1] + '"]').remove();
    5573                    $('a.tag-link-' + data.match(/tag_ID=(\d+)/)[1]).remove();
    56 
     74                    nextFocus.trigger( 'focus' );
     75                    message = wp.i18n.__( 'The selected tag has been deleted.' );
     76           
    5777                } else if ( '-1' == r ) {
    58                     $('#ajax-response').empty().append('<div class="notice notice-error"><p>' + wp.i18n.__( 'Sorry, you are not allowed to do that.' ) + '</p></div>');
    59                     tr.children().css('backgroundColor', '');
     78                    message = wp.i18n.__( 'Sorry, you are not allowed to do that.' );
     79                    $('#ajax-response').empty().append('<div class="notice notice-error"><p>' + message + '</p></div>');
     80                    resetRowAfterFailure( tr );
    6081
    6182                } else {
    62                     $('#ajax-response').empty().append('<div class="notice notice-error"><p>' + wp.i18n.__( 'An error occurred while processing your request. Please try again later.' ) + '</p></div>');
    63                     tr.children().css('backgroundColor', '');
     83                    message = wp.i18n.__( 'An error occurred while processing your request. Please try again later.' );
     84                    $('#ajax-response').empty().append('<div class="notice notice-error"><p>' + message + '</p></div>');
     85                    resetRowAfterFailure( tr );
    6486                }
     87                wp.a11y.speak( message, 'assertive' );
    6588            });
    66 
    67             tr.children().css('backgroundColor', '#f33');
    6889        }
    6990
    7091        return false;
    7192    });
     93
     94    /**
     95     * Restores the original UI state of a table row after an AJAX failure.
     96     *
     97     * @param {jQuery} tr The table row to reset.
     98     * @return {void}
     99     */
     100    function resetRowAfterFailure( tr ) {
     101        tr.children().css( 'backgroundColor', '' );
     102        tr.css( 'pointer-events', '' );
     103        tr.find( ':input, a' ).prop( 'disabled', false ).removeAttr( 'tabindex' );
     104    }
    72105
    73106    /**
Note: See TracChangeset for help on using the changeset viewer.