Pagination.Paginator (simple_pagination v0.3.1)

This module provides live pagination for a given query, paired with helper components that organize and present large sets of data in a user-friendly way. It allows data to be divided into smaller, more manageable pages and provides controls, such as "next page," "previous page," and page numbers, to navigate through them.

In addition to pagination, this module offers sorting, filtering, and search capabilities that allow users to further refine and customize the data they view."

Here's a sample index.html.heex:

  <.search_filter_tag paginator={@things} label="Find" />
  <.page_tag paginator={@things} delta={1} />
  <table>
    <thead>
      <tr>
        <td style="width:15%"><.order_tag label="id" order_by={:id} paginator={@things} /></td>
        <td style="width:85%"><.order_tag label="title" order_by={:title} paginator={@things} /></td>
      </tr>
    </thead>
  <%= for t <- @things.data do %>
    <tr>
      <td><%= t.id %></td>
      <td><%= t.title %></td>
    </tr>
  <% end %>
  </table>

@things is a Pagination.PaginatorState that includes pagination parameters and the resulting dataset.

Do note that you can place filters_tag, page_tag and order_tag pretty much anywhere in your page code.

All changes are handled via event. The paginate event must be handled in index.ex

  def mount(params, _session, socket),
    do: {:ok, assign(socket, things: Things.paginate(params))}

  def handle_event("paginate" = event, params, socket),
    do: {:noreply, assign(socket, things: Things.paginate(socket.assigns.things, params))}

The Things context is the place where the initial query is fed to the paginator:any()

  def paginate(
        attrs,
        %PaginatorState{} = pg \ %PaginatorState{
          filters: [title: ""],
          per_page_items: [5, 25, 0],
          order_by: {:asc, :title}
        }
      ) do
    list_things_query()
    |> maybe_apply_advanced_filtering(attrs)
    |> Pagination.Paginator.paginate(Pagination.Paginator.change(pg, attrs), Repo)
  end

Check the Pagination.PaginatorState structure for more details about pagination parameters. If complex filtering is required, create and add maybe_apply_advanced_filtering/2 and refine the query as needed.

If for some reason you need to specify which elements are to be returned by the select statement, just pass them as last attribute to paginate(

  Pagination.Paginator.paginate(query, paginator_state, Repo, [:id, :title])

Link to this section Summary

Functions

Updates the PaginatorState using given data to change order, page and filters.

This function paginates and filters the given query and returns an updated Pagination.PaginatorState.

Link to this section Functions

Link to this function

change(pg, attrs)

Updates the PaginatorState using given data to change order, page and filters.

attrs is a map.

Link to this function

paginate(query, pg, repo, selected_fields \\ [])

This function paginates and filters the given query and returns an updated Pagination.PaginatorState.

repo is your application Ecto.Repo.

Please note that you can add your own pagination extensions or complex filters by modifying the query before feeding it to paginate/3.

list_things_query()
|> apply_my_own_filters(pg_or_my_own_attributes)
|> Pagination.Paginator.paginate(pg, Repo)