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
change(pg, attrs)
@spec change(Pagination.PaginatorState.t(), map()) :: Pagination.PaginatorState.t()
Updates the PaginatorState using given data to change order, page and filters.
attrs
is a map.
paginate(query, pg, repo, selected_fields \\ [])
@spec paginate(Ecto.Query.t(), Pagination.PaginatorState.t(), Ecto.Repo.t(), list()) :: Pagination.PaginatorState.t()
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)