Table Filter

Mode

Skin

Theme

Overview & How It Works

The ln-table-coordinator component is applied to a container element via <section data-ln-table-coordinator> enclosing an ln-table, search controls, and filter popovers. It acts as a Layer 2 mediator: listening for bubbling ln-filter:change events to toggle active indicator classes (.ln-filter-active) on column header buttons, and capturing the page / hotkey to instantly focus the search input.

When a user clicks a clear action ([data-ln-table-clear]), the coordinator resets search fields and unchecks active filter checkboxes in one coordinated step. It never manipulates or renders table rows directly, leaving data indexing to ln-table and filter logic to ln-filter.

Employee Directory

Name
Department
Role
Status
Location
Ana Petrova Engineering Senior Developer Active Skopje
Marko Nikolov Design UI Designer Active Skopje
Ivan Stojanovski Engineering Backend Developer Inactive Bitola
Sara Dimitrova Marketing Content Lead Active Skopje
Elena Ristova Design UX Researcher On Leave Ohrid
Toni Angelov QA QA Engineer Active Skopje
Boris Ilievski Engineering DevOps Engineer Active Skopje
Kristina Gjorgjevska Finance Accountant Active Bitola
Darko Mitevski Finance Financial Analyst Inactive Skopje
Maja Kostadinova HR HR Manager Active Skopje
Petar Blazevski Engineering System Admin Active Prilep
Aleksandar Naumov Engineering Frontend Developer On Leave Skopje
Vesna Todorova HR HR Specialist Active Ohrid
Lidija Petrovska Engineering Security Engineer Active Skopje
Nikola Trajkovski Marketing SEO Specialist Active Bitola
Jovana Milosevska QA QA Lead Active Skopje
Stefan Georgiev Design Motion Designer Inactive Skopje
Teodora Angelova Finance Budget Analyst Active Prilep

How It Works

  • Global search — ln-search dispatches ln-search:change on the data-ln-table wrapper. ln-table intercepts and filters rows in-memory — no custom script needed.
  • Per-column filters — ln-filter dispatches ln-filter:change on the table wrapper. ln-table maps filter keys to columns via data-ln-table-filter-col on <th>. Multiple columns combine with AND; within a column, values use OR. When active, .ln-filter-active is toggled on the filter <button> — the funnel icon turns accent color.
  • Popover pattern (canonical) — All columns use ln-popover with static authored checkboxes in <ul>/<li>. Each popover's data-ln-filter targets the table wrapper ID. Options come from the domain enum — including zero-record options like "Product".
  • Sort — via data-ln-sort on a <ul> inside <th>. Click cycles ascending → descending → unsorted; the cycle order is CSS-driven, not JS.

Popover Pattern

Filter trigger in <th>, popover with static authored checkboxes in <ul>/<li>. The data-ln-filter on the <ul> targets the table wrapper ID. The <th> needs data-ln-table-filter-col so ln-table maps the filter key to the column. Options come from the domain enum — not derived from the visible dataset.

<!-- th: data-ln-table-filter-col maps the filter key to this column -->
<th data-ln-table-filter-col="dept">
    Department
    <button class="table-filter" type="button"
            data-ln-table-col-filter
            data-ln-popover-for="filter-dept"
            aria-label="Filter department">
        <svg class="ln-icon" aria-hidden="true"><use href="#ln-icon-filter"></use></svg>
    </button>
</th>

<!-- Popover: sibling to [data-ln-table], NOT inside it -->
<!-- ln-popover teleports this to body on open — escapes overflow clipping -->
<div data-ln-popover id="filter-dept">
    <!-- Optional search targets the OPTIONS UL id, never the table id -->
    <input type="search" placeholder="Search..."
           data-ln-search-for="filter-dept-list">
    <ul id="filter-dept-list" data-ln-filter="my-table" data-ln-search="" data-ln-search-items="label">
        <li><label><input type="checkbox" data-ln-filter-key="dept" data-ln-filter-reset checked> All</label></li>
        <li><label><input type="checkbox" data-ln-filter-key="dept" data-ln-filter-value="IT"> IT</label></li>
        <li><label><input type="checkbox" data-ln-filter-key="dept" data-ln-filter-value="HR"> HR</label></li>
        <!-- Domain enum options — include zero-record options (e.g. Legal if no Legal rows exist) -->
        <li><label><input type="checkbox" data-ln-filter-key="dept" data-ln-filter-value="Legal"> Legal</label></li>
    </ul>
</div>

Deprecated: Inline Dropdown Pattern

The previous pattern using ln-dropdown embedded inside a <th> is deprecated. It caused clipping issues due to overflow: hidden on the table's parent container. Use the popover pattern above for all column filters.

Search Integration

ln-search dispatches ln-search:change on the target element. When the target is a data-ln-table wrapper, ln-table intercepts the event, calls preventDefault(), and handles filtering in-memory. No custom script needed.

<!-- Search input targets the ln-table wrapper -->
<input type="search" placeholder="Search..." data-ln-search-for="my-table">

<!-- ln-table wrapper -->
<div data-ln-table data-ln-search="" id="my-table">
    <table>...</table>
</div>