Persist user list filters in Xataface without redirects.
The user_filter_prefs module stores and restores filters for the main list view
(-action=list) on a per-user, per-table basis.
- Restores filters on
list,mobile_filter_dialog,ajax_count_results,xf_infinite_scroll. - Persists filters only on
list. - Supports
sessionordbbackend. - Apply detection supports both markers:
-ufp-apply(module) and-xf-filter-apply(core mobile dialog). - Registers a core
list_settingsaction (ufp_unfilter) for clear filters, with native Xataface action rendering and i18n support. - Skips technical query parameters by default.
- Fully excludes related contexts (
-relationship,-related:*). - Supports
-qf=unfilterwithout redirect. - Normalizes no-filter placeholders (
=) so they are not persisted as active filters. - Keeps behavior self-contained in the module (no core Xataface patch required).
- Xataface 2.x or later
- PHP with mysqli extension (only when using
backend=db)
- Copy
modules/user_filter_prefsinto your applicationmodulesdirectory. - Add to
[_modules]inconf.ini:
modules_user_filter_prefs=modules/user_filter_prefs/user_filter_prefs.php- Add module config in
conf.ini:
[user_filter_prefs]
enabled=1
backend=session
auto_create_table=0
use_session_cache=1
disabled_tables=
exclude_keys=skip,-skip,-limit,-sort,-action,-table,-relationship,-qf,-cursor,--msg
include_keys=-searchenabled:1|0backend:session|dbtable_name: storage table name (db backend only)auto_create_table:1|0(db backend only)use_session_cache:1|0disabled_tables: comma-separated table names where the module is disabledexclude_keys: comma-separated query keys never persistedinclude_keys: comma-separated-prefixed keys explicitly allowed
Defaults:
enabled=1backend=dbtable_name=dataface__filter_preferencesauto_create_table=1use_session_cache=1disabled_tables=(empty)exclude_keys=skip,-skip,-limit,-sort,-action,-table,-relationship,-qf,-cursor,--msginclude_keys=-search
To disable this module for selected tables, configure disabled_tables:
[user_filter_prefs]
disabled_tables=logs,audit_trail,temp_resultsNotes:
- Matching is exact and case-sensitive.
- Only valid table identifiers are accepted (
A-Z,a-z,0-9,_). - Disabled tables skip both save and restore behavior.
- Does nothing for anonymous users.
- Does nothing for unsupported actions.
- Does nothing in related context.
- Clears stored preferences when
-qf=unfilteris used onlist. - Exposes clear-filters through the
ufp_unfilteraction inlist_settings. - Detects explicit Apply from filter flows via
-ufp-apply=1and-xf-filter-apply=1. - Saves explicit filters only on
list. - Restores saved filters into query, GET, and REQUEST when needed.
field=is treated as no-filter placeholder ("All") and is not persisted.field==remains a valid explicit filter value (for workflows that use it).- This normalization prevents stale placeholder filters from polluting persisted preferences.
Xataface uses different UI flows for desktop result filters (use_xataface2_result_filters) and mobile dialog (mobile_filter_dialog).
- Desktop: filter query is built by result list JS.
- Mobile: filter query is rebuilt by mobile dialog JS and may include placeholder values.
The module handles both flows by normalizing source values during persistence, so active filters remain consistent across list reloads.
If your ApplicationDelegate (or table delegates) apply default prefilters,
you should skip them during an explicit unfilter flow.
The module exposes unfilter intent using one of these request signals:
-qf=unfilter
Recommended pattern:
$isUserUnfilter = (
(isset($query['-qf']) and $query['-qf'] == 'unfilter')
);Then guard default prefilter blocks with and !$isUserUnfilter.
Notes:
- Unfilter contract is based on
-qf=unfilteronly.
[user_filter_prefs]
backend=db
auto_create_table=1
table_name=dataface__filter_preferencesStorage columns:
usernametablekeyvalueupdated_at
- Related list filters are intentionally not persisted.
- Array query values are not persisted.
-prefixed keys are excluded unless whitelisted viainclude_keys.- The standard mobile dialog does not expose an explicit "only empty values" UX for all field types.
- Apply desktop filters and verify persistence after reload.
- Apply mobile filters (including multi-select OR) and verify list results and persisted state.
- Use clear filters (
ufp_unfilteror-qf=unfilter) and verify preferences are removed. - Verify no core files are required to be modified.
- Xataface forum: http://xataface.com/forum
GPL-2.0-or-later. See LICENSE.
1.1.1