Backpex.Filters.Boolean behaviour (Backpex v0.23.0)

Copy Markdown View Source

The boolean filter renders one checkbox per given option, hence multiple options can apply at the same time. Instead of implementing a query callback, you need to define predicates for each option leveraging Ecto.Query.dynamic/2.

Warning

Note that only query elements will work as a predicate that also work in an Ecto.Query.where/3.

If none is selected, the filter does not change the query. If multiple options are selected they are logically reduced via orWhere.

See the following example for an implementation of a boolean filter for a published field.

defmodule MyAppWeb.Filters.EventPublished do
  use Backpex.Filters.Boolean

  @impl Backpex.Filter
  def label, do: "Published?"

  @impl Backpex.Filters.Boolean
  def options do
    [
      %{
        label: "Published",
        key: "published",
        predicate: dynamic([x], x.published)
      },
      %{
        label: "Not published",
        key: "not_published",
        predicate: dynamic([x], not x.published)
      }
    ]
  end
end

use Backpex.Filters.Boolean

When you use Backpex.Filters.Boolean, the Backpex.Filters.Boolean module will set @behavior Backpex.Filters.Boolean. In addition it will add a render and render_form function in order to display the corresponding filter. It will also implement the Backpex.Filter.query function to define a boolean query.

Summary

Callbacks

The list of options for the select filter.

Functions

Validates that all selected values exist in the options list.

Finds the label for a given option key.

Converts a list of option values to their corresponding labels.

Transforms options list into a map of keys to predicates. The keys are strings, as the selected values of the filter are, even if the options have atom keys.

Callbacks

options(assigns)

@callback options(assigns :: map()) :: [map()]

The list of options for the select filter.

Each option is a map with a label, a key and a predicate. The key may be a string or an atom; keys are compared as strings, so predicates/1 returns a map with string keys.

Functions

changeset(changeset, field, options)

Validates that all selected values exist in the options list.

Returns the changeset unchanged if all values are valid, or adds an error if any value is not found in options.

find_option_label(options, key)

Finds the label for a given option key.

Returns empty string if the key is not found.

Examples

iex> options = [
...>   %{label: "Published", key: "published"},
...>   %{label: "Not published", key: "not_published"}
...> ]
iex> Backpex.Filters.Boolean.find_option_label(options, "published")
"Published"

iex> options = [%{label: "Published", key: "published"}]
iex> Backpex.Filters.Boolean.find_option_label(options, "unknown")
""

iex> options = [%{label: "Published", key: "published"}]
iex> Backpex.Filters.Boolean.find_option_label(options, :published)
"Published"

maybe_query(predicates, query)

option_value_to_label(options, values)

Converts a list of option values to their corresponding labels.

Returns a list with labels interspersed with commas for display.

Examples

iex> options = [
...>   %{label: "Published", key: "published"},
...>   %{label: "Featured", key: "featured"}
...> ]
iex> Backpex.Filters.Boolean.option_value_to_label(options, ["published", "featured"])
["Published", ", ", "Featured"]

iex> options = [%{label: "Published", key: "published"}]
iex> Backpex.Filters.Boolean.option_value_to_label(options, ["published"])
["Published"]

iex> options = [%{label: "Published", key: "published"}]
iex> Backpex.Filters.Boolean.option_value_to_label(options, [])
[]

iex> options = [%{label: "Published", key: "published"}]
iex> Backpex.Filters.Boolean.option_value_to_label(options, ["unknown"])
[""]

predicates(options)

Transforms options list into a map of keys to predicates. The keys are strings, as the selected values of the filter are, even if the options have atom keys.

Examples

iex> import Ecto.Query
iex> options = [
...>   %{label: "Published", key: "published", predicate: dynamic([x], x.published == true)},
...>   %{label: "Featured", key: "featured", predicate: dynamic([x], x.featured == true)}
...> ]
iex> result = Backpex.Filters.Boolean.predicates(options)
iex> is_map(result) and Map.has_key?(result, "published") and Map.has_key?(result, "featured")
true

iex> import Ecto.Query
iex> predicate = dynamic([x], x.published == true)
iex> Backpex.Filters.Boolean.predicates([%{label: "Published", key: :published, predicate: predicate}])
%{"published" => predicate}

iex> Backpex.Filters.Boolean.predicates([])
%{}

query(query, options, attribute, value, assigns)

render(assigns)

Attributes

  • value (:any) (required)
  • options (:list) (required)

render_form(assigns)

Attributes

  • form (:any) (required)
  • field (:atom) (required)
  • value (:any) (required)
  • options (:list) (required)
  • errors (:list) - Defaults to [].