Skip to main content

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.

ソース情報

リポジトリ
naymspace/backpex
ソースの最終更新活動
2026年4月10日 10:14
検出された SKILL.md の言語
英語
スター
844
フォーク
80

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
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.
# Creating Backpex Filters When the user wants to add a filter: 1. Pick the right filter type from the quick reference 2. Generate the filter module 3. Wire it into the LiveResource's `filters/0` callback ## Quick Reference | 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 `true` - `type/1`: Ecto type for validation (default `:string`), receives assigns - `changeset/3`: custom changeset validation (default: no-op) - `validate/2`: public validation API, builds changeset from `type/1` and `changeset/3` ## Boolean Filter Multiple options selectable via checkboxes, combined with OR. Predicates use `Ecto.Query.dynamic/2`. ```elixir 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 ``` ## Select Filter Single-value dropdown. Default `query/4` does `WHERE field = value`. ```elixir 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 ``` ## MultiSelect Filter 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. ## Range Filter Renders "From" and "To" inputs. Note: `type/0` is arity 0, not arity 1. ```elixir 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`. ## Custom Filter 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. ```elixir 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 ``` ## Wiring Into a LiveResource `filters/0` returns a keyword list. Each key is the schema field atom being filtered. ```elixir @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 ``` ### Filter map keys | 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)}]` | ## Conventions - **Module naming**: `MyAppWeb.Filters.<Resource><FilterName>` (e.g. `MyAppWeb.Filters.PostPublished`) - **File location**: `lib/my_app_web/filters/<snake_case_name>.ex` - **The keyword list key** in `filters/0` must match the database column or foreign key - **Always `import Ecto.Query`** when using `dynamic/2` or writing custom queries - **Database queries in `options/1`** are fine since it runs at render time
GitHubで見る