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년 10월 7일 06:43
감지된 SKILL.md 언어
영어
스타
845
포크
79

설치 방법

기본적으로 소스를 먼저 확인하는 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에서 보기