com um clique
create-filter
// Use when adding a filter to a Backpex LiveResource, creating a filter module, or the user asks about filtering data in Backpex index views.
// Use when adding a filter to a Backpex LiveResource, creating a filter module, or the user asks about filtering data in Backpex index views.
Use when scaffolding a new Backpex LiveResource, setting up admin CRUD views, or configuring adapter_config, fields, filters, and routing for a resource.
Use when creating custom Backpex field types, implementing the Backpex.Field behaviour, or adding fields to a LiveResource's fields/0 callback.
Use when upgrading Backpex to a newer version, handling breaking changes, or migrating code after a version bump. Also use when the user asks about what changed between versions.
Use when creating custom Backpex item actions, adding action buttons to table rows or the show page, or modifying the default edit/delete/show actions.
Use when creating Backpex resource actions for global operations like bulk exports, invitations, imports, or any action that applies to the resource as a whole rather than individual items.
| name | create-filter |
| description | Use when adding a filter to a Backpex LiveResource, creating a filter module, or the user asks about filtering data in Backpex index views. |
When the user wants to add a filter:
filters/0 callback| Type | Use for | use module | Key callbacks |
|---|---|---|---|
| Boolean | Checkbox predicates (published yes/no) | Backpex.Filters.Boolean | options/1 returning %{label, key, predicate} maps |
| Select | Single-value dropdown | Backpex.Filters.Select | prompt/0, options/1 returning {label, value} tuples |
| MultiSelect | Multi-value dropdown with checkboxes | Backpex.Filters.MultiSelect | prompt/0, options/1 returning {label, value} tuples |
| Range | Date, datetime, or number ranges | Backpex.Filters.Range | type/0 returning :date, :datetime, or :number |
| Custom | Anything else | Backpex.Filter | query/4, render/1, render_form/1 |
All built-in filters auto-implement query/4, render/1, and render_form/1. Do NOT re-implement those unless you need custom behavior.
All filters have these overridable callbacks with defaults:
label/0: filter label (optional callback, can also be set in filters/0 map)can?/1: visibility control, receives assigns, default truetype/1: Ecto type for validation (default :string), receives assignschangeset/3: custom changeset validation (default: no-op)validate/2: public validation API, builds changeset from type/1 and changeset/3Multiple options selectable via checkboxes, combined with OR. Predicates use Ecto.Query.dynamic/2.
defmodule MyAppWeb.Filters.PostPublished do
use Backpex.Filters.Boolean
import Ecto.Query
@impl Backpex.Filter
def label, do: "Published?"
@impl Backpex.Filters.Boolean
def options(_assigns) do
[
%{label: "Published", key: "published", predicate: dynamic([x], x.published)},
%{label: "Not published", key: "not_published", predicate: dynamic([x], not x.published)}
]
end
end
Single-value dropdown. Default query/4 does WHERE field = value.
defmodule MyAppWeb.Filters.PostCategorySelect do
use Backpex.Filters.Select
import Ecto.Query
alias MyApp.Repo
@impl Backpex.Filter
def label, do: "Category"
@impl Backpex.Filters.Select
def prompt, do: "Select category ..."
@impl Backpex.Filters.Select
def options(_assigns) do
from(c in MyApp.Category, select: {c.name, c.id}, order_by: c.name) |> Repo.all()
end
end
Same as Select but allows multiple values. Default query/4 does WHERE field IN values. Uses prompt/0 (implement with @impl Backpex.Filters.Select) and options/1 (implement with @impl Backpex.Filters.MultiSelect). Note: MultiSelect internally sets @behaviour Backpex.Filters.Select for the prompt callback.
Renders "From" and "To" inputs. Note: type/0 is arity 0, not arity 1.
defmodule MyAppWeb.Filters.PostLikeRange do
use Backpex.Filters.Range
@impl Backpex.Filters.Range
def type, do: :number
@impl Backpex.Filter
def label, do: "Likes"
end
For dates use def type, do: :date. For datetimes use def type, do: :datetime.
Use Backpex.Filter directly when no built-in type fits. You must implement query/4, render/1, and render_form/1. Note: use Backpex.Filter does not import HEEx sigils. You need use Phoenix.Component for ~H support.
defmodule MyAppWeb.Filters.PostCustom do
use Phoenix.Component
use Backpex.Filter
import Ecto.Query
@impl Backpex.Filter
def label, do: "Custom"
@impl Backpex.Filter
def query(query, attribute, value, _assigns) do
where(query, [x], field(x, ^attribute) == ^value)
end
@impl Backpex.Filter
def render(assigns) do
~H"{@value}"
end
@impl Backpex.Filter
def render_form(assigns) do
~H"""
<input type="text" name={@form[@field].name} value={@value} class="input input-sm" />
"""
end
end
filters/0 returns a keyword list. Each key is the schema field atom being filtered.
@impl Backpex.LiveResource
def filters do
[
published: %{
module: MyAppWeb.Filters.PostPublished
},
category_id: %{
module: MyAppWeb.Filters.PostCategorySelect,
label: "Category"
},
likes: %{
module: MyAppWeb.Filters.PostLikeRange,
label: "Likes",
presets: [
%{label: "Over 100", values: fn -> %{"start" => 100, "end" => nil} end},
%{label: "1-99", values: fn -> %{"start" => 1, "end" => 99} end}
]
}
]
end
| Key | Required | Description |
|---|---|---|
:module | yes | The filter module |
:label | no | Overrides the module's label/0 |
:default | no | Pre-selected value on initial page load |
:presets | no | Quick-select shortcuts: [%{label: String.t(), values: (-> value)}] |
MyAppWeb.Filters.<Resource><FilterName> (e.g. MyAppWeb.Filters.PostPublished)lib/my_app_web/filters/<snake_case_name>.exfilters/0 must match the database column or foreign keyimport Ecto.Query when using dynamic/2 or writing custom queriesoptions/1 are fine since it runs at render time