With single checkbox option, $this->value always true

Created on 21 May 2025, 11 days ago

Problem/Motivation

Using bef 6.0.6

Exposing a views filter plugin and then choosing the "single checkbox" option in BEF, the $this->value always comes out true.

Steps to reproduce

Create a view
create a custom views filter plugin that extends Drupal\views\Plugin\views\filter\BooleanOperator. expose it and update the bef options to select checkbox

in the query function we need to read the value of the checkbox.

Normally this is done through $this->value

however when using a single checkbox option in BEF $this->value is always 1.

To resolve this, note the following two methods:

  /**
   * 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;
  }

AND

  /**
   * {@inheritdoc}
   */
  public function query() {
    $identifier = $this->options['expose']['identifier'];
    $input = $this->view->getExposedInput();
    $include_sessions = isset($input[$identifier]) && $input[$identifier] === '1';

    if (!$include_sessions) {
      // Example logic.
      $alias = $this->query->ensureTable('paragraph__field_title', 'paragraphs_item_field_data');
      $this->query->addWhereExpression(1, "$alias.field_title_value IS NOT NULL");
    }
  }

Full working example:

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, however it would be simpler if $this->value had the expected value as it does when using a radio selection or other type of option.

Proposed resolution

See workaround, TBD for an improved better_exposed_filter solution

Remaining tasks

TBD

User interface changes

TBD

API changes

TBD

Data model changes

N/A

πŸ’¬ Support request
Status

Active

Version

6.0

Component

Code

Created by

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

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

Comments & Activities

Production build 0.71.5 2024