Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough
May 19 2020
May 19

Web accessibility helps to make the world wide web usable for everyone. Many of the most common accessibility issues making sites difficult or impossible to use in a non-traditional way can be easily fixed. 

The following hook modifies any exposed view filter to have aria labels on each form element as well as inserts the view name into the form element, form element label, form actions wrapper, and form submit button ID. (E.g. edit-submit-[VIEW_NAME]-[VIEW_DISPLAY])

Developers need to ensure that page markup does not contain duplicate IDs because many screen readers and assistive technologies use IDs within the page as landmarks for the user to easily parse the content.

The addition of aria-labels acts as an agnostic accessibility feature to inform the user the purpose of the element:

/**
* Implements hook_form_alter().
*/
function MYMODULE_form_alter(&$form, FormStateInterface &$form_state, $form_id) {
 // Add aria-labels to views exposed filters.
 if ($form_id === 'views_exposed_form' && strpos($form['#id'], '-block-') !== FALSE) {
   // Assumed structure (e.g. views_exposed_form_[view_name]_[block_name]).
   $exploded_form_id = explode('views_exposed_form_', str_replace('-', '_', $form['#id']));

   if (isset($exploded_form_id[1]) && !empty($exploded_form_id[1])) {
     // Get the view id.
     $view = explode('_block_', $exploded_form_id[1]);
     $view = isset($view[0]) ? $view[0] : '';

     if (!empty($view)) {
       // Get the view display id.
       $view_display = explode($view . '_', $exploded_form_id[1]);
       $view_display = $view_display[1];
       // Get the view display title.
       $view = Views::getView($view);
       $view->setDisplay($view_display);
       $clean_view_display_title = Html::getClass($view->getTitle());

       foreach ($form['#info'] as $info) {
         if (isset($form[$info['value']])) {
           $clean_info_value = Html::getClass($info['value']);

           // Add an aria-label to the form element.
           $form[$info['value']]['#attributes']['aria-label'] = $view->getTitle() . ' ' . trim($info['label'], ':');
           // Update the id on the form element and label.
           $form[$info['value']]['#id'] = 'edit-' . $clean_view_display_title . '-' . $clean_info_value;
         }
       }

       if (isset($form['actions'])) {
         $form['actions']['#id'] = 'edit-actions-' . $clean_view_display_title;

         // Update the id on the submit button.
         if (isset($form['actions']['submit'])) {
           $form['actions']['submit']['#id'] .= '-' . $clean_view_display_title;
         }
       }
     }
   }
 }
}

This second hook modifies any Table view display to prepend the view name and view display name to the table header ID attribute and corresponding table row header attribute (e.g. [VIEW_NAME]--[VIEW_DISPLAY]--[EXISITNG_ID]):

/**
* Implements template_preprocess_views_view_table().
*/
function MYMODULE_preprocess_views_view_table(&$variables) {
 $view_name = Html::getClass($variables['view']->id());
 $view_display = Html::getClass($variables['view']->getDisplay()->display['id']);
 $id_prefix = $view_name . '--' . $view_display . '--';

 // Update each table header 'id' to be
 // prepended with [VIEW_NAME]--[VIEW_DISPLAY]--.
 foreach ($variables['header'] as $header_key => $header) {
   if (
     isset($header['attributes']) &&
     isset($header['attributes']->storage()['id'])
   ) {
     $variables['header'][$header_key]['attributes']->setAttribute('id', $id_prefix . $header['attributes']->storage()['id']);
   }
 }

 // Update each row 'headers' to be
 // prepended with [VIEW_NAME]--[VIEW_DISPLAY]--.
 foreach ($variables['rows'] as $row_key => $row) {
   if (isset($row['columns']) && !empty($row['columns'])) {
     foreach ($row['columns'] as $column_key => $column) {
       if (
         isset($column['attributes']) &&
         isset($column['attributes']->storage()['headers'])
       ) {
         $variables['rows'][$row_key]['columns'][$column_key]['attributes']->setAttribute('headers', $id_prefix . $column['attributes']->storage()['headers']);
       }
     }
   }
 }
}

Comment below for other ideas, or if you need help using these. 
 

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web