Skip to content

Commit

Permalink
Issue #19: Select as Links should be within a list element for A11Y.
Browse files Browse the repository at this point in the history
Fixes #19.
  • Loading branch information
laryn authored Apr 10, 2024
1 parent 34afe34 commit 73f8aab
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 49 deletions.
57 changes: 39 additions & 18 deletions better_exposed_filters.theme.inc
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,7 @@ function theme_select_as_links($vars) {
$element['#value'] = check_plain($element['#value']);
}

$items = array();
// Go through each filter option and build the appropriate link or plain text.
foreach ($element['#options'] as $option => $elem) {
if (!empty($element['#hidden_options'][$option])) {
Expand Down Expand Up @@ -546,12 +547,6 @@ function theme_select_as_links($vars) {
$element_output = '';
// Custom ID for each link based on the <select>'s original ID.
$id = backdrop_html_id($element['#id'] . '-' . $key);
$elem = array(
'#id' => $id,
'#markup' => '',
'#type' => 'bef-link',
'#name' => $id,
);

$link_options = array();
// Add "active" class to the currently active filter link.
Expand All @@ -565,31 +560,58 @@ function theme_select_as_links($vars) {
else {
$url = bef_replace_query_string_arg($name, $key, $multiple, FALSE, $path);
}
$elem['#children'] = l($value, $url, $link_options);
$element_output = theme('form_element', array('element' => $elem));
// $elem['#children'] = l($value, $url, $link_options);
$link = array(
'#title' => $value,
'#href' => $url,
'#options' => $link_options,
'#type' => 'link',
);

if (!empty($element['#settings']['combine_param']) && $element['#name'] == $element['#settings']['combine_param'] && !empty($element['#settings']['toggle_links'])) {
$sort_pair = explode(' ', $key);
if (count($sort_pair) == 2) {
// Highlight the link if it is the selected sort_by (can be either
// asc or desc, it doesn't matter).
if (strpos($selected_options[0], $sort_pair[0]) === 0) {
if (strpos($selected_options[0], $sort_pair[0]) === 0) {
$element_output = str_replace('form-item', 'form-item selected', $element_output);
}
}
}
$output .= $element_output;
$items[] = array(
'data' => backdrop_render($link),
'class' => array(
'form-type-bef-link',
'form-item',
'form-item-' . $key,
),
'id' => $id,
);

}
}
if (!empty($items)) {
$list = theme('item_list', array(
'items' => $items,
'attributes' => array(
'class' => array(
'bef-links',
'form-item',
),
),
'wrapper_attributes' => array(
'class' => array(
'bef-select-as-links',
),
),
));

$properties = array(
'#description' => isset($element['#bef_description']) ? $element['#bef_description'] : '',
'#children' => $output,
);

$output = '<div class="bef-select-as-links">';
$output .= theme('form_element', array('element' => $properties));
$list_wrapper = array(
'#description' => isset($element['#bef_description']) ? $element['#bef_description'] : '',
'#children' => $list,
);
$output .= render($list_wrapper);
}

// Add attribute that hides the select form element.
$vars['element']['#attributes']['style'] = 'display: none;';
Expand All @@ -604,7 +626,6 @@ function theme_select_as_links($vars) {
$output .= '<input type="hidden" class="bef-new-value" name="' . $name . '" value="' . $element['#value'] . '" />';
}
}
$output .= '</div>';

return $output;
}
Expand Down
14 changes: 14 additions & 0 deletions css/better_exposed_filters.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ fieldset.bef-select-as-checkboxes-fieldset.collapsed legend {
.bef-slider.ui-slider-horizontal {
margin-top: 6px;
}

.bef-slider.ui-slider-vertical {
margin-top: 12px;
}
Expand All @@ -29,3 +30,16 @@ fieldset.bef-select-as-checkboxes-fieldset.collapsed legend {
.views-exposed-form .views-exposed-widget {
display: block;
}

/*
* Don't show Select as Links as list items by default, for backwards
* compatibility.
*/
.bef-links {
list-style: none;
}

.bef-links li.form-type-bef-link {
display: inline;
margin: 0;
}
38 changes: 19 additions & 19 deletions tests/better_exposed_filters.test
Original file line number Diff line number Diff line change
Expand Up @@ -532,9 +532,9 @@ class BEF_TestLinks extends BEF_TestBase {
$this->backdropGet('bef_test_page');

// Verify the type filter, which is multi-select.
$this->assertFieldByXpath('//div[@id="edit-type-wrapper"]//div[@id="edit-type-post"]/a[contains(@href, "?type%5B0%5D=post")]', NULL, 'Correct link for "post" filter');
$this->assertFieldByXpath('//div[@id="edit-type-wrapper"]//div[@id="edit-type-page"]/a[contains(@href, "?type%5B0%5D=page")]', NULL, 'Correct link for "page" filter');
$this->assertFieldByXpath('//div[@id="edit-type-wrapper"]//div[@id="edit-type-bef-test"]/a[contains(@href, "?type%5B0%5D=bef_test")]', NULL, 'Correct link for "bef test" filter');
$this->assertFieldByXpath('//div[@id="edit-type-wrapper"]//li[@id="edit-type-post"]/a[contains(@href, "?type%5B0%5D=post")]', NULL, 'Correct link for "post" filter');
$this->assertFieldByXpath('//div[@id="edit-type-wrapper"]//li[@id="edit-type-page"]/a[contains(@href, "?type%5B0%5D=page")]', NULL, 'Correct link for "page" filter');
$this->assertFieldByXpath('//div[@id="edit-type-wrapper"]//li[@id="edit-type-bef-test"]/a[contains(@href, "?type%5B0%5D=bef_test")]', NULL, 'Correct link for "bef test" filter');

// @todo A couple of assertions are disabled here to make the 7.x branch
// pass the tests for now. We need to find out what the correct behavior
Expand All @@ -555,20 +555,20 @@ class BEF_TestLinks extends BEF_TestBase {
$this->clickLink('Yes');

// Verify the type filter, which is multi-select.
$this->assertFieldByXpath('//div[@id="edit-type-wrapper"]//div[@id="edit-type-post"]/a[contains(@href, "?status_1=1&type%5B0%5D=post")]', NULL, 'Correct link for "post" filter');
$this->assertFieldByXpath('//div[@id="edit-type-wrapper"]//div[@id="edit-type-page"]/a[contains(@href, "?status_1=1&type%5B0%5D=page")]', NULL, 'Correct link for "page" filter');
$this->assertFieldByXpath('//div[@id="edit-type-wrapper"]//div[@id="edit-type-bef-test"]/a[contains(@href, "?status_1=1&type%5B0%5D=bef_test")]', NULL, 'Correct link for "bef test" filter');
$this->assertFieldByXpath('//div[@id="edit-type-wrapper"]//li[@id="edit-type-post"]/a[contains(@href, "?status_1=1&type%5B0%5D=post")]', NULL, 'Correct link for "post" filter');
$this->assertFieldByXpath('//div[@id="edit-type-wrapper"]//li[@id="edit-type-page"]/a[contains(@href, "?status_1=1&type%5B0%5D=page")]', NULL, 'Correct link for "page" filter');
$this->assertFieldByXpath('//div[@id="edit-type-wrapper"]//li[@id="edit-type-bef-test"]/a[contains(@href, "?status_1=1&type%5B0%5D=bef_test")]', NULL, 'Correct link for "bef test" filter');

// None of the type filter options should be marked as "active."
$this->assertNoFieldByXpath('//div[@id="edit-type-wrapper"]//a[contains(@class, "Active")]', NULL, 'No "type" link options are marked as "active"');

// Verify the status filter, which is single select.
/// $this->assertFieldByXpath('//div[@id="edit-status-1-wrapper"]//div[@id="edit-status-1-1"]/a[contains(@href, "?status_1=1")]', NULL, 'Correct link for "status: yes" filter');
/// $this->assertFieldByXpath('//div[@id="edit-status-1-wrapper"]//div[@id="edit-status-1-0"]/a[contains(@href, "?status_1=0")]', NULL, 'Correct link for "status: no" filter');
$this->assertFieldByXpath('//div[@id="edit-status-1-wrapper"]//li[@id="edit-status-1-1"]/a[contains(@href, "?status_1=1")]', NULL, 'Correct link for "status: yes" filter');
$this->assertFieldByXpath('//div[@id="edit-status-1-wrapper"]//li[@id="edit-status-1-0"]/a[contains(@href, "?status_1=0")]', NULL, 'Correct link for "status: no" filter');

// Just the "yes" option should be marked as "active."
$this->assertFieldByXpath('//div[@id="edit-status-1-wrapper"]//div[@id="edit-status-1-1"]/a[contains(@class, "active")]', NULL, 'Correct "active" setting for the "status: yes" filter');
$this->assertNoFieldByXpath('//div[@id="edit-status-1-wrapper"]//div[@id="edit-status-1-0"]/a[contains(@class, "active")]', NULL, 'Correct "active" setting for the "status: no" filter');
$this->assertFieldByXpath('//div[@id="edit-status-1-wrapper"]//li[@id="edit-status-1-1"]/a[contains(@class, "active")]', NULL, 'Correct "active" setting for the "status: yes" filter');
$this->assertNoFieldByXpath('//div[@id="edit-status-1-wrapper"]//li[@id="edit-status-1-0"]/a[contains(@class, "active")]', NULL, 'Correct "active" setting for the "status: no" filter');

// Verify correct links and "active" settings for non-required, boolean
// filters. See https://www.drupal.org/node/2631804.
Expand All @@ -587,15 +587,15 @@ class BEF_TestLinks extends BEF_TestBase {

// Clicking "no" should mark that option as active.
$this->clickLink('No');
$this->assertNoFieldByXpath('//div[@id="edit-status-1-wrapper"]//div[@id="edit-status-1-all"]/a[contains(@class, "active")]', NULL, 'Correct "active" setting for the "status: any" filter');
$this->assertNoFieldByXpath('//div[@id="edit-status-1-wrapper"]//div[@id="edit-status-1-1"]/a[contains(@class, "active")]', NULL, 'Correct "active" setting for the "status: yes" filter');
$this->assertFieldByXpath('//div[@id="edit-status-1-wrapper"]//div[@id="edit-status-1-0"]/a[contains(@class, "active")]', NULL, 'Correct "active" setting for the "status: no" filter');
$this->assertNoFieldByXpath('//div[@id="edit-status-1-wrapper"]//li[@id="edit-status-1-all"]/a[contains(@class, "active")]', NULL, 'Correct "active" setting for the "status: any" filter');
$this->assertNoFieldByXpath('//div[@id="edit-status-1-wrapper"]//li[@id="edit-status-1-1"]/a[contains(@class, "active")]', NULL, 'Correct "active" setting for the "status: yes" filter');
$this->assertFieldByXpath('//div[@id="edit-status-1-wrapper"]//li[@id="edit-status-1-0"]/a[contains(@class, "active")]', NULL, 'Correct "active" setting for the "status: no" filter');

// Clicking "any" should mark that option as active.
$this->clickLink('- Any -');
$this->assertFieldByXpath('//div[@id="edit-status-1-wrapper"]//div[@id="edit-status-1-all"]/a[contains(@class, "active")]', NULL, 'Correct "active" setting for the "status: any" filter');
$this->assertNoFieldByXpath('//div[@id="edit-status-1-wrapper"]//div[@id="edit-status-1-1"]/a[contains(@class, "active")]', NULL, 'Correct "active" setting for the "status: yes" filter');
$this->assertNoFieldByXpath('//div[@id="edit-status-1-wrapper"]//div[@id="edit-status-1-0"]/a[contains(@class, "active")]', NULL, 'Correct "active" setting for the "status: no" filter');
$this->assertFieldByXpath('//div[@id="edit-status-1-wrapper"]//li[@id="edit-status-1-all"]/a[contains(@class, "active")]', NULL, 'Correct "active" setting for the "status: any" filter');
$this->assertNoFieldByXpath('//div[@id="edit-status-1-wrapper"]//li[@id="edit-status-1-1"]/a[contains(@class, "active")]', NULL, 'Correct "active" setting for the "status: yes" filter');
$this->assertNoFieldByXpath('//div[@id="edit-status-1-wrapper"]//li[@id="edit-status-1-0"]/a[contains(@class, "active")]', NULL, 'Correct "active" setting for the "status: no" filter');

// Verify correct "active" settings for filters with default values.
$this->editFilter('status_1', array(
Expand All @@ -604,9 +604,9 @@ class BEF_TestLinks extends BEF_TestBase {
));
$this->saveView();
$this->backdropGet('bef_test_page');
$this->assertNoFieldByXpath('//div[@id="edit-status-1-wrapper"]//div[@id="edit-status-1-all"]/a[contains(@class, "active")]', NULL, 'Correct "active" setting for the "status: any" filter');
$this->assertNoFieldByXpath('//div[@id="edit-status-1-wrapper"]//div[@id="edit-status-1-1"]/a[contains(@class, "active")]', NULL, 'Correct "active" setting for the "status: yes" filter');
$this->assertFieldByXpath('//div[@id="edit-status-1-wrapper"]//div[@id="edit-status-1-0"]/a[contains(@class, "active")]', NULL, 'Correct "active" setting for the "status: no" filter');
$this->assertNoFieldByXpath('//div[@id="edit-status-1-wrapper"]//li[@id="edit-status-1-all"]/a[contains(@class, "active")]', NULL, 'Correct "active" setting for the "status: any" filter');
$this->assertNoFieldByXpath('//div[@id="edit-status-1-wrapper"]//li[@id="edit-status-1-1"]/a[contains(@class, "active")]', NULL, 'Correct "active" setting for the "status: yes" filter');
$this->assertFieldByXpath('//div[@id="edit-status-1-wrapper"]//li[@id="edit-status-1-0"]/a[contains(@class, "active")]', NULL, 'Correct "active" setting for the "status: no" filter');
}

}
Expand Down
19 changes: 7 additions & 12 deletions views/better_exposed_filters_exposed_form_plugin.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1258,16 +1258,10 @@ dateFormat: "dd-mm-yy"
$bef_js['datepicker'] = TRUE;
$bef_js['datepicker_options'] = array();

if ((
// Single Date API-based input element.
isset($form[$filter_id]['value']['#type'])
&& 'date_text' == $form[$filter_id]['value']['#type']
)
// Double Date-API-based input elements such as "in-between".
|| (isset($form[$filter_id]['min']) && isset($form[$filter_id]['max'])
&& 'date_text' == $form[$filter_id]['min']['#type']
&& 'date_text' == $form[$filter_id]['max']['#type']
)) {
// Single or Double (e.g. "in-between") Date API-based input elements.
$single_date = isset($form[$filter_id]['value']['#type']) && 'date_text' == $form[$filter_id]['value']['#type'];
$double_date = isset($form[$filter_id]['min']) && isset($form[$filter_id]['max']) && 'date_text' == $form[$filter_id]['min']['#type'] && 'date_text' == $form[$filter_id]['max']['#type'];
if ($single_date || $double_date) {
/*
* Convert Date API formatting to jQuery formatDate formatting.
*
Expand Down Expand Up @@ -1312,7 +1306,7 @@ dateFormat: "dd-mm-yy"
// ISO-8601 week number of year, weeks starting on Monday (added
// in PHP 4.1.0) Example: 42 (the 42nd week in the year).
// 'W' => ' ',
//

/* Month */
// A full textual representation of a month, such as January or
// March January through December.
Expand All @@ -1328,7 +1322,7 @@ dateFormat: "dd-mm-yy"
'n' => 'm',
// Number of days in the given month 28 through 31.
// 't' => ' ',
//

/* Year */
// Whether it's a leap year 1 if it is a leap year, 0 otherwise.
// 'L' => ' ',
Expand Down Expand Up @@ -1480,6 +1474,7 @@ dateFormat: "dd-mm-yy"

case 'bef_links':
$bef_add_js = TRUE;
$bef_add_css = TRUE;
$form[$filter_id]['#theme'] = 'select_as_links';

// Exposed form displayed as blocks can appear on pages other than
Expand Down

0 comments on commit 73f8aab

Please sign in to comment.