Problem/Motivation

This modules fixes the header problem in CK5 but it would be nice if it focuses on all accessibility issues. I have a custom module with a filter that fixes:
- scope in th
- changing the first th (top left cell) in thead into a tr when it is empty ( ). Sure its better to not leave it empty but when it happens this is better.
- wrap the table in a div to make it scrollable over the x-axes
- add tabindex=0 to the table to make it focussable. in some browsers necesary to make table accessible for keyboard users

One other thing that would be nice to be able to do is to make the top left cell not scope col but scope row while being inside the thead. For example see attached image. The top left cells explains what A B C D are. But A B C and D should be a th aswell for the columns.

Ps. asking for this because I feel you can do this better than I can, I'm not a developing wizard so adding my code so you can see what I did.

class A11yCkeFix extends FilterBase {
  public function process($text, $langcode) {
    // Change the first <th> in <thead> when its content is &nbsp; without creating a new <th>
    $pattern = '/(<thead><tr>)<th>&nbsp;<\/th>/';
    $replacement = '$1<td>&nbsp;</td>';
    $text = preg_replace($pattern, $replacement, $text);

    // Find all theads's
    preg_match_all('/(<thead>.*?<\/thead>)/s', $text, $matches);
    $thead_sections = $matches[0];

    foreach ($thead_sections as $thead) {
      // Add col scope to th in thead
      $modified_thead = preg_replace('/(<th\b(?![^>]*\bscope="col\b)[^>]*)(>)/', '$1 scope="col"$2', $thead);
      $text = str_replace($thead, $modified_thead, $text);
    }

    // Find all tbody's
    preg_match_all('/(<tbody>.*?<\/tbody>)/s', $text, $matches);
    $tbody_sections = $matches[0];

    foreach ($tbody_sections as $tbody) {
      // Add row scope to th in tbody
      $modified_tbody = preg_replace('/(<th\b(?![^>]*\bscope="row\b)[^>]*)(>)/', '$1 scope="row"$2', $tbody);
      $text = str_replace($tbody, $modified_tbody, $text);
    }

    // Wrap div around table and make table focusable
    $text = preg_replace('/<table>/', '<div class="table-responsive"><table tabindex="0">', $text);
    $text = preg_replace('/<\/table>/', '</table></div>', $text);

    $result = new FilterProcessResult($text);
    return $result;
  }
}
CommentFileSizeAuthor
Screenshot 2024-09-19 at 15.07.20.png37.65 KBzebda
Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

zebda created an issue. See original summary.

zebda’s picture

Issue summary: View changes
zebda’s picture

Issue summary: View changes
zebda’s picture

Issue summary: View changes
watergate’s picture

Version: 1.0.0-alpha1 » 2.x-dev
Assigned: Unassigned » watergate
watergate’s picture

Title: Focus on more than headers alone » Don't apply scope attribute for empty <th> elements

watergate’s picture

Title: Don't apply scope attribute for empty <th> elements » Allow manually setting scope attributes and don't apply scope attribute for empty <th> elements
Assigned: watergate » Unassigned
Status: Active » Needs review
Related issues: +#3554443: Add a filter plugin to replace empty <th> elements with <td>

@zebda, thanks for creating this issue and sharing accessibility improvements.

I've created a merge request that ensures empty <th> elements don't receive a scope attribute and that any existing scope attributes aren't overwritten, so manual adjustments remain possible. This MR also includes additional test coverage for these cases. Any feedback is welcome.

To replace empty <th> elements with <td> elements, I've opened a separate issue to handle it as a new/additional text filter. This allows administrators to choose whether they want to apply this functionality. See #3554443: Add a filter plugin to replace empty <th> elements with <td>

Regarding wrapping tables in a scrollable container and adding tabindex=0, that functionality is already provided by the Responsive Table Filter module. To improve table accessibility, both modules can be installed together on a site, as they complement each other.

As for allowing the top-left header cell in the <thead> to use scope="row", that’s an interesting (edge) case. At this moment, I don't see an easy way to do this automatically. Still, with the currently suggested changes, you can set it manually (by modifying the table's source directly for that cell).

  • watergate committed f0faa120 on 2.x
    [#3475552] feat: Allow manually setting scope attributes and don't apply...
watergate’s picture

Status: Needs review » Fixed

I've applied the suggested changes to the 2.x version of this module. Please reopen this ticket if a backport of this functionality is desired (ideally, provide a merge request).

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.