Skip to main content
MybringDesign System

Filtering

Table filtering principles

Standard table filtering

Shipment Recipient Sent Recieved Status
987654321 Mieow Corp 09.08.2024 11.50 12.08.2024 11.38 Delivered
123456789 Shiba Shipping Industries 10.08.2024 12.12 14.08.2024 11.05 Delivered
HTML
  <div class="flex gas align-ic">
    <label class="form__label" for="search-input">Shipment or recipient
      <input type="text" id="search-input" class="form__control w16r" placeholder="Search" aria-controls="result-content" />
    </label>
    <label class="form__label" for="status-select">Status
      <select id="status-select" class="form__control wauto maxw100p" aria-controls="result-content">
        <option>All statuses</option>
        <option selected data-filter="status">Delivered</option>
        <option data-filter="status">In transit</option>
      </select>
    </label>
    <button id="clear-filters" class="btn-link--dark mts mls">Clear all</span></button>
  </div>
  
  <div id="result-content">
    <div id="result-message" role="status" class="screen-reader-text mlm" aria-live="polite"></div>
  
    <table id="example-table" class="mb-table mts">
      <thead>
        <tr>
          <th scope="col">Shipment</th>
          <th scope="col">Recipient</th>
          <th scope="col">Sent</th>
          <th scope="col">Recieved</th>
          <th scope="col">Status</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td data-filter="shipment"><a href="#">987654321</a></td>
          <td data-filter="recipient">Mieow Corp</td>
          <td>09.08.2024 11.50</td>
          <td>12.08.2024 11.38</td>
          <td data-filter="status"><span class="mb-badge mb-badge--green">Delivered</span></td>
        </tr>
        <tr>
          <td data-filter="shipment"><a href="#">123456789</a></td>
          <td data-filter="recipient">Shiba Shipping Industries</td>
          <td>10.08.2024 12.12</td>
          <td>14.08.2024 11.05</td>
          <td data-filter="status"><span class="mb-badge mb-badge--green">Delivered</span></td>
        </tr>
        <tr hidden>
          <td data-filter="shipment"><a href="#">456789123</a></td>
          <td data-filter="recipient">Toad Trampolines Co.</td>
          <td>02.09.2024 10.38</td>
          <td></td>
          <td data-filter="status"><span class="mb-badge">In transit</span></td>
        </tr>
      </tbody>
    </table>
  </div>
  
  <div id="rowselect-pagination" class="flex flex-wrap align-ic gas">
    <div class="mb-rows-select">
      <select id="rows-select" class="form__control wauto maxw100p">
        <option>25</option>
        <option>50</option>
        <option>100</option>
      </select>
      <label for="rows-select">Shipments per page</label>
    </div>
    <nav aria-label="Pagination">
      <ul class="pagination">
        <li>
          <button title="Previous page">
            <span
              data-mybicon="mybicon-arrow-left"
              data-mybicon-class="icon-ui"
            ></span>
          </button>
        </li>
        <li>
          <button>1</button>
        </li>
        <li>
          <button aria-current="page">2</button>
        </li>
        <li>
          <button>3</button>
        </li>
        <li>
          <button>4</button>
        </li>
        <li>
          <button title="Next page">
            <span
              data-mybicon="mybicon-arrow-right"
              data-mybicon-class="icon-ui"
            ></span>
          </button>
        </li>
      </ul>
    </nav>
  </div>

Extended table filtering

When a table has a lot of filters, or not all filters are used often.

Shipment Recipient Sent Recieved Contact Person Country Status
987654321 Mieow Corp 09.08.2024 11.50 12.08.2024 11.38 Tom Sweden Delivered
123456701 Shiba Shipping Industries 10.08.2024 12.12 14.08.2024 11.05 Mr. Woof Norway Delivered
123456702 Shiba Shipping Industries 10.08.2024 12.30 14.08.2024 11.05 Mr. Woof Norway Delivered
123456703 Shiba Shipping Industries 13.09.2024 17.02 15.09.2024 11.21 Mr. Woof Norway Delivered
123456704 Shiba Shipping Industries 07.10.2024 10.44 10.10.2024 12.00 Mr. Woof Norway Delivered
123456705 Shiba Shipping Industries 11.10.2024 14.34 14.10.2024 11.22 Mr. Woof Norway Delivered
456789123 Toad Trampolines Co. 02.09.2024 10.38 Skippy Norway In transit
HTML
  <div class="flex align-ic gam justify-csb flex-wrap mbm">
    <label class="form__label mb0" for="search-input-extended">
      Shipment or recipient
      <input type="text" id="search-input-extended" aria-controls="result-content" class="form__control w16r mb0" placeholder="Search"/>
    </label>
    <div class="flex flex-wrap gas align-sfe">
      <button id="extended-search-btn" aria-controls="extended-search" aria-expanded="false" class="btn mb0 relative">
        <span id="rotate" data-mybicon="mybicon-arrow-right" data-mybicon-class="icon-ui mrxs rotate"></span>
        Extended filtering
        <span id="active-extended" class="mb-dot"></span>
      </button>
      <button class="btn mb0">
        <span data-mybicon="mybicon-download_file" data-mybicon-class="icon-ui mrxs"></span>
        Export
      </button>
      <button title="Column customization" aria-controls="column-customization" class="btn mb0" id="column-custom-btn">
        <span data-mybicon="mybicon-columns-edit" data-mybicon-class="icon-ui mlxs"></span>
      </button>
    </div>
  </div>
  
  <div class="flex flex-wrap bg-gray2 mbm pam pbs gas dn" id="extended-search" aria-expanded="false">
    <label class="form__label" for="status-select-extended">Status
      <select id="status-select-extended" class="form__control wauto maxw100p" aria-controls="result-content">
        <option>All statuses</option>
        <option selected data-filter="status">Delivered</option>
        <option data-filter="status">In transit</option>
      </select>
    </label>
    <label class="form__label" for="country-select">
      Country
      <select id="country-select" class="form__control wauto maxw100p" aria-controls="result-content">
        <option selected>All countries</option>
        <option data-filter="country">Norway</option>
        <option data-filter="country">Sweden</option>
        <option data-filter="country">Denmark</option>
      </select>
    </label>
    <label class="form__label" for="contact-select">
      Contact person
      <select id="contact-select" class="form__control wauto maxw100p" aria-controls="result-content">
        <option selected>All contacts</option>
        <option data-filter="contact">Tom</option>
        <option data-filter="contact">Mr. Woof</option>
        <option data-filter="contact">Skippy</option>
      </select>
    </label>
  </div>
  
  <div class="flex flex-wrap gas">
    <button id="clear-filters-extended" class="btn-link--dark mrs">
      Clear all
    </button>
    <button id="input-chip" class="btn-link--dark dn" title="Search value"><span id="input-chip-val"></span><span
      data-mybicon="mybicon-cross" data-mybicon-class="icon-ui mls"></span></button>
    <button id="select-chip" class="btn-link--dark" title="Selected status"><span
      id="select-chip-val">Delivered</span><span data-mybicon="mybicon-cross"
      data-mybicon-class="icon-ui mls"></span></button>
    <button id="country-chip" class="btn-link--dark dn" title="Selected country"><span id="country-chip-val"></span><span
      data-mybicon="mybicon-cross" data-mybicon-class="icon-ui mls"></span></button>
    <button id="contact-chip" class="btn-link--dark dn" title="Selected contact person"><span
      id="contact-chip-val"></span><span data-mybicon="mybicon-cross" data-mybicon-class="icon-ui mls"></span></button>
  </div>
  
  <div id="result-content">
    <div id="result-message-extended" role="status" class="screen-reader-text mlm mtl" aria-live="polite"></div>
    <table id="example-table-extended" class="mb-table mts">
      <thead>
        <tr>
          <th scope="col">Shipment</th>
          <th scope="col">Recipient</th>
          <th scope="col">Sent</th>
          <th scope="col">Recieved</th>
          <th scope="col">Contact Person</th>
          <th scope="col">Country</th>
          <th scope="col">Status</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td data-filter="shipment"><a href="#">987654321</a></td>
          <td data-filter="recipient">Mieow Corp</td>
          <td>09.08.2024 11.50</td>
          <td>12.08.2024 11.38</td>
          <td>Tom</td>
          <td data-filter="country">Sweden</td>
          <td data-filter="status"><span class="mb-badge mb-badge--green">Delivered</span></td>
        </tr>
        <tr>
          <td data-filter="shipment"><a href="#">123456701</a></td>
          <td data-filter="recipient">Shiba Shipping Industries</td>
          <td>10.08.2024 12.12</td>
          <td>14.08.2024 11.05</td>
          <td>Mr. Woof</td>
          <td data-filter="country">Norway</td>
          <td data-filter="status"><span class="mb-badge mb-badge--green">Delivered</span></td>
        </tr>
        <tr>
          <td data-filter="shipment"><a href="#">123456702</a></td>
          <td data-filter="recipient">Shiba Shipping Industries</td>
          <td>10.08.2024 12.30</td>
          <td>14.08.2024 11.05</td>
          <td>Mr. Woof</td>
          <td data-filter="country">Norway</td>
          <td data-filter="status"><span class="mb-badge mb-badge--green">Delivered</span></td>
        </tr>
        <tr>
          <td data-filter="shipment"><a href="#">123456703</a></td>
          <td data-filter="recipient">Shiba Shipping Industries</td>
          <td>13.09.2024 17.02</td>
          <td>15.09.2024 11.21</td>
          <td>Mr. Woof</td>
          <td data-filter="country">Norway</td>
          <td data-filter="status"><span class="mb-badge mb-badge--green">Delivered</span></td>
        </tr>
        <tr>
          <td data-filter="shipment"><a href="#">123456704</a></td>
          <td data-filter="recipient">Shiba Shipping Industries</td>
          <td>07.10.2024 10.44</td>
          <td>10.10.2024 12.00</td>
          <td>Mr. Woof</td>
          <td data-filter="country">Norway</td>
          <td data-filter="status"><span class="mb-badge mb-badge--green">Delivered</span></td>
        </tr>
        <tr>
          <td data-filter="shipment"><a href="#">123456705</a></td>
          <td data-filter="recipient">Shiba Shipping Industries</td>
          <td>11.10.2024 14.34</td>
          <td>14.10.2024 11.22</td>
          <td>Mr. Woof</td>
          <td data-filter="country">Norway</td>
          <td data-filter="status"><span class="mb-badge mb-badge--green">Delivered</span></td>
        </tr>
        <tr>
          <td data-filter="shipment"><a href="#">456789123</a></td>
          <td data-filter="recipient">Toad Trampolines Co.</td>
          <td>02.09.2024 10.38</td>
          <td></td>
          <td>Skippy</td>
          <td data-filter="country">Norway</td>
          <td data-filter="status"><span class="mb-badge">In transit</span></td>
        </tr>
      </tbody>
    </table>
  </div>
  
  <div id="rowselect-pagination-extended" class="flex flex-wrap align-ic gas">
    <div class="mb-rows-select">
      <select id="rows-select-extended" class="form__control wauto maxw100p">
        <option>25</option>
        <option>50</option>
        <option>100</option>
      </select>
      <label for="rows-select-extended">Shipments per page</label>
    </div>
    <nav aria-label="Pagination">
      <ul class="pagination">
        <li>
          <button title="Previous page">
            <span data-mybicon="mybicon-arrow-left" data-mybicon-class="icon-ui"></span>
          </button>
        </li>
        <li>
          <button>1</button>
        </li>
        <li>
          <button aria-current="page">2</button>
        </li>
        <li>
          <button>3</button>
        </li>
        <li>
          <button>4</button>
        </li>
        <li>
          <button title="Next page">
            <span data-mybicon="mybicon-arrow-right" data-mybicon-class="icon-ui"></span>
          </button>
        </li>
      </ul>
    </nav>
  </div>

Principles

What to filter

Order filter by usage and importance. Track usage of filters and actions to get valuable insights into user interactions with the tables.

  • Limit the amount of filters and inputs by merging text search fields, removing unused filters and placing rarely used filters into an extended filters area.
  • Evaluate if a filter fills the same function as a column's sorting, and consider using only one of them.

Reference

Positions

Rows per page

Use the rows per page select for large tables with a lot of data. A good starting point for values in the select is 25 - 50 - 100 rows per page. You can add logging to see which values are used the most, and adjust the options and default value.

Wording

"Rows per page" is a good default, but it's even better to be context specific. For instance "Orders per page" or "Shipments per page".

Active filters

  • Active filter is shown in form controls.
  • Include "Clear all" button when a filter or search is active.
  • If the table has extended filters use chips and clear all to show active filters. Chips are not necessary for simple tables with few search and filter options. Use notification dot on button if filter from extended filters is active. If filter is preselected use the wording "reset filter" instead of "clear all".

Reference

  • mb-dot

No results

Hide the entire table and pagination when search or filtering yields no results. Inform the user by displaying a message such as "No results found" instead. We also need to inform users using assistive technology such as screen readers about the change without changing focus. To do this we can

  • Populate an empty ARIA live region with content when there are no results, using aria-live="polite" and role="status".
  • Put aria-controls on elements that will affect the live region, such as search and filter inputs, using the ARIA live region id as value.
  • When searching again after getting "no results" message, let the user know they are getting results by announcing "results found" or "x results found". If search results are dynamic, try to avoid interrupting the user too much by not announcing results found unecessarily often, and introduce a delay to avoid interrupting the user while they are typing.

Pagination

Reset the pagination with each filtering action, as the current page may no longer be accurate. Pagination is not often being used in combination with filtering, and there is no guarantee that the current page will still exist.