1

Client wants to hide some published content from specific Views displays.

Unpublishing the content is not an option: it needs to remain accessible.

I added a boolean exclude_from_view field to several content types.

I planned to add a boolean filter to exclude content from the necessary displays if this field's value was TRUE, but I was surprised to find that when I did so, Views returned no results at all. Setting the boolean filter to NOT FALSE had the same result.

This is happening because the field has been added to the existing content without a default value, so the field returns NULL, which is neither TRUE nor FALSE. (In PHP, NULL is a "falsy" value, but apparently not to Views.)

A little research reveals that a lot of other people have complained about this problem.

Some of them think that boolean fields not set on entities should be considered FALSE, not NULL.

Others wish that NULL fields could be treated as TRUE.

Still others think that Views UI should offer filtering options for "Treat NULL as FALSE" or "Treat NULL as TRUE." (This is a cool idea but it requires patching core, which I'm not necessarily opposed to if it is the best way forward.)

What should I do?

UPDATE 2019-11-13:

Kudos to @no-sssweat for coming up with a viable workaround, which I upvoted below.

I'm still hoping for a better answer because I'm not satisfied with the user experience of the "checkboxes/radio buttons" field widget.

If I just use one value, it shows up as two radio buttons, for N/A and Yes. Adding a No option doesn't make it much better: Works, but UX is not ideal

I think the client would really prefer a boolean checkbox, so I'm holding out for an answer that will give me that.

3 Answers 3

1

Interesting problem, I was able to replicate the issue.

Some of them think that Boolean fields not set on entities should be considered FALSE, not NULL.

Others wish that NULL fields could be treated as TRUE.

Seems like patching core catered towards your needs would make some people unhappy. Unless you add, a new option, an Is Empty (NULL) to it.


A work around solution is to use List (text) OR List (integer) I set mine to 1 | yea

You could make it a select box by switching the field widget from list to checkboxes

Then in Views filter you just set to is none of and it will return all nodes that are not set to "yea".

enter image description here


OR better yet you can select Is Empty (Null)

enter image description here

2
  • 1
    Interesting workaround. Can’t filter on NULL because after nodes are edited, the field has a value, but “Is none of” might work. Commented Nov 13, 2019 at 12:47
  • Thanks for looking at this. I found another approach (drupal.stackexchange.com/a/288289/80164), but your insights were worth an upvote. Commented Nov 14, 2019 at 13:57
1

Just for posterity, here's the approach I ended up using:

The Field Defaults contrib module allowed me to set all null values for the new field in pre-existing content, so I was able to use the boolean checkbox I wanted.

Screenshot of Field Defaults user interface, exposed in field config

There's no need to patch core to deal with this, because it won't happen again with newly-created content. As soon as the node is saved, the field has a sensible default value.

0

Views provides an option for filtering boolean fields on null/not null, but this is not exposed in the Views UI.

Here is a workaround until the work on Issue #2769407 is accepted into Drupal core to alter all boolean filters configured via Views UI with "False" to imply "False or Null".

use Drupal\views\ViewExecutable;

/**
 * Implements hook_views_pre_build().
 */
function MODULENAME_views_pre_build(ViewExecutable $view) {

  // List of views to alter.
  $views_to_alter = ['VIEWMACHINENAME', 'VIEWMACHINENAME'];

  if (!in_array($view->id(), $views_to_alter)) {
    return;
  }

  // Treat NULL values as FALSE on boolean field filters.
  // @todo remove/refactor when #2769407 lands.
  foreach ($view->filter as $key => &$filter) {
    if (
      $filter->getPluginId() == "boolean"
      && $filter->value == 0
    ) {
      $filter->accept_null = TRUE;
    }
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.