MishkaGervaz.Table.Web.Events.RelationFilterHandler behaviour
(MishkaGervaz v0.0.1-alpha.2)
Copy Markdown
View Source
Handles relation filter events for dynamic search, load more, and multi-select.
This module manages server-side state for relation filters that need:
- Async search with database queries
- Paginated option loading
- Multi-select with label resolution
Events Handled
search- Search options by term (debounced)load_more- Load next page of optionsfocus- Open dropdown and load initial optionsclose_dropdown- Close dropdown on click-awaytoggle- Toggle selection in multi-select mode
Public Validation Functions
skip_relation_search_term?/2- Check if a value should be skipped as a filter valuevalid_relation_value?/1- Check if a value is a valid relation filter value (UUID or nil)
Client-Side Alternative
Users with custom JS comboboxes (Tom Select, Headless UI, etc.) can bypass
these events entirely and just use the standard "filter" event to submit
final selected values. These events are for server-managed UI state.
Customization
You can create a custom RelationFilterHandler:
defmodule MyApp.CustomRelationFilterHandler do
use MishkaGervaz.Table.Web.Events.RelationFilterHandler
def handle("toggle", params, state, socket) do
MyApp.Analytics.track("relation_filter_toggle", params)
super("toggle", params, state, socket)
end
endThen configure it in your resource's DSL:
mishka_gervaz do
table do
events do
relation_filter MyApp.CustomRelationFilterHandler
end
end
endSee MishkaGervaz.Table.Web.Events,
MishkaGervaz.Table.Web.DataLoader.RelationLoader,
MishkaGervaz.Table.Types.Filter.Relation,
and the sibling handlers SanitizationHandler, RecordHandler,
SelectionHandler, BulkActionHandler, HookRunner.
Summary
Functions
Checks if a relation filter value should be skipped (not treated as a filter value).
Checks if a value is a valid relation filter value for the given ID type.
Types
@type params() :: map()
@type socket() :: Phoenix.LiveView.Socket.t()
@type state() :: MishkaGervaz.Table.Web.State.t()
Callbacks
Functions
Checks if a relation filter value should be skipped (not treated as a filter value).
For relation filters with :search or :search_multi mode, this returns true
if the value is not valid for the filter's ID type - meaning it's likely a search
term that should not be used as the actual filter value.
The id_type is determined from the related resource's primary key type:
:uuid- Validates as UUID:uuid_v7- Validates as UUID (same format):integer- Validates as integer:string- Any non-empty string is valid
Examples
iex> skip_relation_search_term?(%{type: :relation, mode: :search, id_type: :uuid}, "some search text")
true
iex> skip_relation_search_term?(%{type: :relation, mode: :search, id_type: :uuid}, "550e8400-e29b-41d4-a716-446655440000")
false
iex> skip_relation_search_term?(%{type: :relation, mode: :search, id_type: :integer}, "123")
false
iex> skip_relation_search_term?(%{type: :text}, "any value")
false
Checks if a value is a valid relation filter value for the given ID type.
ID Types
:uuid/:uuid_v7- Must be a valid UUID string:integer- Must be a valid integer string:string- Any non-empty string is valid
Special Values
"__nil__"- Always valid, indicates "no selection" or "null"
Examples
iex> valid_relation_value?("__nil__", :uuid)
true
iex> valid_relation_value?("550e8400-e29b-41d4-a716-446655440000", :uuid)
true
iex> valid_relation_value?("123", :integer)
true
iex> valid_relation_value?("search text", :uuid)
false
iex> valid_relation_value?("any-string", :string)
true