Single on/off option does not work if the filter is not required

Created on 5 January 2016, over 9 years ago
Updated 11 April 2024, about 1 year ago

Followup from #2618500: Single on/off checkbox is always checked β†’ . If the filter is not required, the single on/off option doesn't work as expected. This is because the boolean field is now trinary (yes/no/both).

Suggested fix: only allow the single on/off checkbox option on required boolean fields, but remove the "#required" attribute so that the UX is not complicated by an input-required flag when input is not actually required.

Steps to reproduce:

  1. Navigate to /admin/structure/views/add, View name: on-off test, "Continue & edit"
  2. Edit the existing "Content: Published" filter: tick "Expose this filter...", untick "Required", click "Apply"
  3. Note that the filter operates correctly using Views' select element
  4. Edit "Exposed form style": set to "Better Exposed Filters" and click "Apply"
  5. On the BEF settings page, set the "status" filter display to "Single on/off checkbox" and click "Apply"
  6. Note the same content displays in Views' preview regardless of the "Published" checkbox state
  7. Save the view and navigate to /on-off-test, same content displays regardless of the "Published" checkbox state

Also note, if you set the default value of the filter to "No" it will still render as checked when the page is first loaded. But only if the filter is not required.

πŸ› Bug report
Status

Needs work

Version

6.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States mikeker

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    @rohit.rawat619 that patch not sure matches when was in the D7 ticket. How come?

    @andypost what needs to be ported?

  • Status changed to Postponed: needs info about 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave
  • Status changed to Closed: outdated 12 months ago
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave
  • πŸ‡¨πŸ‡¦Canada joseph.olstad

    @smustgrave, please reopen this, Andypost is correct, this patch needs to be ported. I'm using Drupal 10.4 with a checkbox exposed bef , the issues reported by Andy Post relating to the patch that needs porting is still unresolved for 8.x-3.x or whatever it's called now.

  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Will 8.x-.3x is unsupported and 6.0.x is essentially unsupported just not marking it

  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    May be a dup of https://www.drupal.org/project/better_exposed_filters/issues/2921024 πŸ› Not possible to unselect the checkbox Active

  • πŸ‡¨πŸ‡¦Canada joseph.olstad

    Ok I have figured out a solution for this, here is the crux of it:

    mymodule.views.inc

    
    use Drupal\Core\StringTranslation\TranslatableMarkup;
    
    /**
     * Implements hook_views_data_alter().
     */
    function mymodule_views_data_alter(array &$data) {
      $data['paragraphs_item_field_data']['include_session_paragraph'] = [
        'title' => new TranslatableMarkup('Show event sessions'),
        'help' => new TranslatableMarkup('Show event "session" paragraphs toggle filter.  When off/false, only calendar_entry paragraphs are included in the results.'),
        'filter' => [
          'id' => 'include_session_paragraph',
          'group' => 'MyModule',
        ],
      ];
    }
    

    src/Plugin/views/filter/IncludeSessionParagraph.php

    
    namespace Drupal\mymodule\Plugin\views\filter;
    
    use Drupal\views\Plugin\views\filter\BooleanOperator;
    use Drupal\Core\Form\FormStateInterface;
    
    /**
     * Controls paragraph filtering by presence of field_title (i.e. calendar_entry only).
     *
     * @ingroup views_filter_handlers
     *
     * @ViewsFilter("include_session_paragraph")
     */
    class IncludeSessionParagraph extends BooleanOperator {
    
      /**
       * Workaround for BEF checkbox filters.
       */
      public function acceptExposedInput($input) {
        if (!parent::acceptExposedInput($input)) {
          return FALSE;
        }
    
        // If the filter value is not present in the input, reject.
        // This is the critical fix for BEF + Single On/Off checkbox.
        $identifier = $this->options['expose']['identifier'];
        if (!array_key_exists($identifier, $input)) {
          return FALSE;
        }
    
        return TRUE;
      }
    
      /**
       * {@inheritdoc}
       */
      protected function defineOptions() {
        $options = parent::defineOptions();
        return $options;
      }
    
      /**
       * {@inheritdoc}
       */
      public function buildOptionsForm(&$form, FormStateInterface $form_state) {
        parent::buildOptionsForm($form, $form_state);
        $form['value']['#title'] = $this->t('Show event sessions');
      }
    
      /**
       * {@inheritdoc}
       */
      public function query() {
        $identifier = $this->options['expose']['identifier'];
        $input = $this->view->getExposedInput();
        $include_sessions = isset($input[$identifier]) && $input[$identifier] === '1';
    
        if (!$include_sessions) {
          $alias = $this->query->ensureTable('paragraph__field_title', 'paragraphs_item_field_data');
          $this->query->addWhereExpression(1, "$alias.field_title_value IS NOT NULL");
        }
      }
    
    
    }
    
    

    So this filter is added and in bef configured as a single checkbox in the advanced options of bef

    The crux was adding the acceptExposedInput method which sets up the expose identifier and adjusting the query method to capture the input

    (from the query method) like this:

        $identifier = $this->options['expose']['identifier'];
        $input = $this->view->getExposedInput();
        $include_sessions = isset($input[$identifier]) && $input[$identifier] === '1';
    

    So, I got it working without a patch.

    Otherwise the value is always true no matter what was selected so could not use $this->value , instead use the approach mentioned above until this is fixed.

  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Fix will ultimately be over in πŸ› Not possible to unselect the checkbox Active

Production build 0.71.5 2024