Current section
Files
Jump to
Current section
Files
lib/cinder/filters/text.ex
defmodule Cinder.Filters.Text do
@moduledoc """
Text filter implementation for Cinder tables.
Provides text-based filtering with support for different operators
like contains, equals, starts_with, etc.
"""
@behaviour Cinder.Filter
use Phoenix.Component
require Ash.Query
import Cinder.Filter
@impl true
def render(column, current_value, theme, _assigns) do
filter_options = Map.get(column, :filter_options, [])
placeholder = get_option(filter_options, :placeholder, "Filter #{column.label}...")
assigns = %{
column: column,
current_value: current_value || "",
placeholder: placeholder,
theme: theme
}
~H"""
<input
type="text"
name={field_name(@column.field)}
value={@current_value}
placeholder={@placeholder}
phx-debounce="300"
class={@theme.filter_text_input_class}
{@theme.filter_text_input_data}
/>
"""
end
@impl true
def process(raw_value, column) when is_binary(raw_value) do
trimmed = String.trim(raw_value)
if trimmed == "" do
nil
else
filter_options = Map.get(column, :filter_options, [])
operator = get_option(filter_options, :operator, :contains)
case_sensitive = get_option(filter_options, :case_sensitive, false)
%{
type: :text,
value: trimmed,
operator: operator,
case_sensitive: case_sensitive
}
end
end
def process(_raw_value, _column), do: nil
@impl true
def validate(value) do
case value do
%{type: :text, value: val, operator: op} when is_binary(val) and is_atom(op) ->
op in [:contains, :equals, :starts_with, :ends_with, :not_contains, :not_equals]
_ ->
false
end
end
@impl true
def default_options do
[
operator: :contains,
case_sensitive: false,
placeholder: nil
]
end
@impl true
def empty?(value) do
case value do
nil -> true
"" -> true
%{value: ""} -> true
%{value: nil} -> true
_ -> false
end
end
@impl true
def build_query(query, field, filter_value) do
%{type: :text, value: value, operator: operator} = filter_value
case_sensitive = Map.get(filter_value, :case_sensitive, false)
# Use case-insensitive search unless explicitly set to case-sensitive
search_value = if case_sensitive, do: value, else: Ash.CiString.new(value)
# Use the centralized helper which supports direct, relationship, and embedded fields
Cinder.Filter.Helpers.build_ash_filter(query, field, search_value, operator)
end
end