LiveFilter.QuickFilters (LiveFilter v0.1.0)

View Source

Composable filter builder functions for common patterns.

This module provides simple, focused functions for creating filters. Each function returns a Filter struct that can be used individually or combined with others. There's no magic - just convenience functions that save you from writing boilerplate.

Philosophy

These are building blocks, not a framework. Use what you need, ignore what you don't, and write your own when these don't fit.

Examples

# Use individual builders
search = QuickFilters.search_filter("user input")
status = QuickFilters.multi_select_filter(:status, [:active, :pending])
date = QuickFilters.date_range_filter(:created_at, {~D[2025-01-01], ~D[2025-01-31]})

# Combine into a filter group
filter_group = %FilterGroup{
  filters: [search, status, date] |> Enum.reject(&is_nil/1)
}

# Or use in your own functions
def build_my_filters(params) do
  [
    params["q"] && QuickFilters.search_filter(params["q"]),
    params["urgent"] == "true" && QuickFilters.boolean_filter(:is_urgent, true),
    # ... your custom logic
  ]
  |> Enum.reject(&is_nil/1)
end

Summary

Functions

Create an array/tags filter.

Create a boolean filter.

Example handler for multi-select toggle.

Example event handler for search with debounce.

Extract multiple filter values at once.

Extract array value from a filter group.

Extract boolean value from a filter group.

Extract date range from a filter group.

Extract multi-select values from a filter group.

Extract numeric value from a filter group.

Extract optional filters (filters not in exclusion list).

Extract search query from a filter group.

Build multiple filters from a parameter map.

Create a multi-select filter for enum fields.

Create a numeric filter.

Create a search filter.

Functions

array_filter(field, values, opts \\ [])

Create an array/tags filter.

Options

  • :operator - Operator (default: :contains_any)
  • :type - Field type (default: :array)

Examples

# Contains any
QuickFilters.array_filter(:tags, ["urgent", "bug"])

# Contains all
QuickFilters.array_filter(:tags, ["urgent", "bug"], operator: :contains_all)

boolean_filter(field, value, opts \\ [])

Create a boolean filter.

Options

  • :operator - Operator to use (default: :equals)
  • :true_only - Only create filter for true values (default: false)

Examples

# Simple boolean
QuickFilters.boolean_filter(:is_active, true)

# Only filter when true
QuickFilters.boolean_filter(:is_urgent, value, true_only: true)

date_range_filter(field, date_or_range, opts \\ [])

Create a date range filter.

Handles both date tuples and preset strings.

Options

  • :operator - Operator to use (default: :between for ranges, :equals for single dates)
  • :type - Field type (default: :date)
  • :timezone - Timezone for date calculations (default: "Etc/UTC")

Examples

# Date range
QuickFilters.date_range_filter(:created_at, {~D[2025-01-01], ~D[2025-01-31]})

# Single date
QuickFilters.date_range_filter(:due_date, ~D[2025-01-15])

# Preset (requires LiveFilter.DateUtils)
QuickFilters.date_range_filter(:created_at, "last_30_days")

example_multi_select_handler(socket, field, value, atom)

Example handler for multi-select toggle.

This is just an example pattern.

example_search_handler(socket, query, opts \\ [])

Example event handler for search with debounce.

This is just an example - implement your own based on your needs.

extract_all(filter_group, extractors, opts \\ [])

Extract multiple filter values at once.

Options

  • :socket - If provided, applies values to socket assigns

Examples

extractors = [
  search_query: &extract_search_query/1,
  selected_statuses: fn fg -> extract_multi_select(fg, :status) end,
  is_urgent: fn fg -> extract_boolean(fg, :is_urgent, default: false) end
]

result = QuickFilters.extract_all(filter_group, extractors)
#=> %{search_query: "test", selected_statuses: [:active], is_urgent: false}

# With socket
socket = QuickFilters.extract_all(filter_group, extractors, socket: socket)

extract_array(filter_group, field, opts \\ [])

Extract array value from a filter group.

Options

  • :default - Default value if not found (default: [])

Examples

filter_group = %FilterGroup{
  filters: [
    %Filter{field: :tags, operator: :contains_any, value: ["urgent", "bug"]}
  ]
}

QuickFilters.extract_array(filter_group, :tags)
#=> ["urgent", "bug"]

extract_boolean(filter_group, field, opts \\ [])

Extract boolean value from a filter group.

Options

  • :default - Default value if not found (default: nil)

Examples

filter_group = %FilterGroup{
  filters: [
    %Filter{field: :is_urgent, operator: :equals, value: true}
  ]
}

QuickFilters.extract_boolean(filter_group, :is_urgent)
#=> true

extract_date_range(filter_group, field)

Extract date range from a filter group.

Returns the date value or range tuple.

Examples

filter_group = %FilterGroup{
  filters: [
    %Filter{field: :due_date, operator: :between, value: {~D[2025-01-01], ~D[2025-01-31]}}
  ]
}

QuickFilters.extract_date_range(filter_group, :due_date)
#=> {~D[2025-01-01], ~D[2025-01-31]}

extract_multi_select(filter_group, field, opts \\ [])

Extract multi-select values from a filter group.

Returns a list of selected values for enum/select fields.

Options

  • :single_value - Return single value instead of list for :equals (default: false)

Examples

filter_group = %FilterGroup{
  filters: [
    %Filter{field: :status, operator: :in, value: [:active, :pending]}
  ]
}

QuickFilters.extract_multi_select(filter_group, :status)
#=> [:active, :pending]

extract_numeric(filter_group, field)

Extract numeric value from a filter group.

Returns the numeric value or range.

Examples

filter_group = %FilterGroup{
  filters: [
    %Filter{field: :price, operator: :greater_than, value: 99.99}
  ]
}

QuickFilters.extract_numeric(filter_group, :price)
#=> 99.99

extract_optional_filters(filter_group, excluded_fields, opts \\ [])

Extract optional filters (filters not in exclusion list).

Returns a map with :active_optional_filters and :optional_filter_values.

Options

  • :socket - If provided, applies values to socket assigns

Examples

excluded = [:status, :_search]
result = QuickFilters.extract_optional_filters(filter_group, excluded)
#=> %{
#=>   active_optional_filters: [:project, :tags],
#=>   optional_filter_values: %{project: "phoenix", tags: ["bug"]}
#=> }

extract_search_query(filter_group, opts \\ [])

Extract search query from a filter group.

Looks for search filters and returns the query value.

Options

  • :field - Field to look for (default: :_search)
  • :operator - Operator to match (default: any)

Examples

filter_group = %FilterGroup{
  filters: [
    %Filter{field: :_search, operator: :custom, value: "search term"}
  ]
}

QuickFilters.extract_search_query(filter_group)
#=> "search term"

from_params(params, opts \\ [])

Build multiple filters from a parameter map.

This is a convenience function for handling common parameter patterns.

Options

  • :definitions - List of {param_key, builder_fun} tuples
  • :prefix - Parameter key prefix to strip

Examples

params = %{
  "q" => "search term",
  "status" => ["active", "pending"],
  "urgent" => "true"
}

filters = QuickFilters.from_params(params,
  definitions: [
    {"q", fn v -> search_filter(v) end},
    {"status", fn v -> multi_select_filter(:status, v) end},
    {"urgent", fn "true" -> boolean_filter(:urgent, true); _ -> nil end}
  ]
)

multi_select_filter(field, values, opts \\ [])

Create a multi-select filter for enum fields.

Options

  • :operator - Operator to use (default: :in for lists, :equals for single values)
  • :type - Field type (default: :enum)
  • :reject_empty - Whether to return nil for empty values (default: true)

Examples

# Multiple values
QuickFilters.multi_select_filter(:status, [:active, :pending])

# Single value (uses :equals operator)
QuickFilters.multi_select_filter(:status, :active)

# Force operator
QuickFilters.multi_select_filter(:tags, ["urgent", "bug"], operator: :contains_all)

numeric_filter(field, value, opts \\ [])

Create a numeric filter.

Options

  • :operator - Operator (default: :equals)
  • :type - :integer or :float (default: auto-detect)

Examples

# Exact value
QuickFilters.numeric_filter(:price, 99.99)

# Comparison
QuickFilters.numeric_filter(:age, 21, operator: :greater_than_or_equal)

# Range
QuickFilters.numeric_filter(:score, {80, 100}, operator: :between)

search_filter(query, opts \\ [])

Create a search filter.

By default creates a virtual _search filter that your application can expand to search multiple fields. You can customize everything.

Options

  • :field - Field name (default: :_search)
  • :operator - Operator to use (default: :custom)
  • :type - Field type (default: :string)
  • :min_length - Minimum query length to create filter (default: 0)
  • :trim - Whether to trim whitespace (default: true)

Examples

# Simple search
QuickFilters.search_filter("user query")

# Search specific field
QuickFilters.search_filter("john", field: :author_name, operator: :contains)

# Require minimum length
QuickFilters.search_filter(query, min_length: 3)

Returns nil if query is empty or below min_length.