Current section
Files
Jump to
Current section
Files
lib/rummage_phoenix/hooks/views/paginate_view.ex
defmodule Rummage.Phoenix.PaginateView do
@moduledoc """
View Helper for Pagination in Rummage for bootstrap views.
Usage:
```elixir
defmodule MyApp.ProductView do
use MyApp.Web, :view
use Rummage.Phoenix.View, only: [:paginate]
end
```
OR
```elixir
defmodule MyApp.ProductView do
use MyApp.Web, :view
use Rummage.Phoenix.View
end
```
"""
use Rummage.Phoenix.ThemeAdapter
@doc """
This macro includes the helper functions for pagination
Provides helper functions `pagination_link/3` for creating pagination links in an html.eex
file of using `Phoenix`.
Usage:
Just add the following code in the index template. Make sure that you're passing
rummage from the controller. Please look at the
[README](https://github.com/Excipients/rummage_phoenix) for more details
```elixir
pagination_link(@conn, @rummage)
```
"""
def pagination_link(conn, rummage, opts \\ []) do
pagination_links do
[first_page_link(conn, rummage, opts)] ++
[previous_page_link(conn, rummage, opts)] ++
middle_page_links(conn, rummage, opts) ++
[next_page_link(conn, rummage, opts)] ++
[last_page_link(conn, rummage, opts)]
end
end
def pagination_with_all_link(conn, rummage, opts \\ []) do
pagination_links do
[first_page_link(conn, rummage, opts)] ++
[previous_page_link(conn, rummage, opts)] ++
middle_page_links(conn, rummage, opts) ++
[next_page_link(conn, rummage, opts)] ++
[last_page_link(conn, rummage, opts)] ++
[all_page_link(conn, rummage, opts)]
end
end
def all_page_link(conn, rummage, opts) do
paginate_params = rummage.paginate
per_page = paginate_params.per_page
label = opts[:all_label] || "All"
case per_page == -1 do
true ->
page_link("#", :disabled, do: label)
false ->
page_link(index_path(opts, [conn, :index, transform_params(rummage, -1, 1, opts)]),
do: label
)
end
end
# def per_page_link(conn, rummage, opts \\ []) do
# import Phoenix.HTML.Form
# paginate_params = rummage.paginate
# form_for conn, index_path(opts, [conn, :index]), [as: :params, method: :get], fn(form) ->
# input = number_input(form, :per_page, value: paginate_params.per_page)
# submit = submit("Set Per Page", class: "btn btn-default")
# [input, submit]
# end
# end
defp first_page_link(conn, rummage, opts) do
paginate_params = rummage.paginate
page = paginate_params.page
per_page = paginate_params.per_page
# max_page_links = String.to_integer(paginate_params["max_page_links"] || "4")
label = opts[:first_label] || "First"
case page == 1 do
true ->
page_link("#", :disabled, do: label)
false ->
page_link(index_path(opts, [conn, :index, transform_params(rummage, per_page, 1, opts)]),
do: label
)
end
end
defp previous_page_link(conn, rummage, opts) do
paginate_params = rummage.paginate
page = paginate_params.page
per_page = paginate_params.per_page
label = opts[:previous_label] || "Previous"
case page <= 1 do
true ->
page_link("#", :disabled, do: label)
false ->
page_link(
index_path(opts, [conn, :index, transform_params(rummage, per_page, page - 1, opts)]),
do: label
)
end
end
defp middle_page_links(conn, rummage, opts) do
paginate_params = rummage.paginate
page = paginate_params.page
per_page = paginate_params.per_page
max_page = paginate_params.max_page
max_page_links = opts[:max_page_links] || Rummage.Phoenix.default_max_page_links()
lower_limit =
cond do
page <= div(max_page_links, 2) -> 1
page >= max_page - div(max_page_links, 2) -> Enum.max([0, max_page - max_page_links]) + 1
true -> page - div(max_page_links, 2)
end
upper_limit = lower_limit + max_page_links - 1
Enum.map(lower_limit..upper_limit, fn page_num ->
cond do
page == page_num ->
page_link("#", :active, do: page_num)
page_num > max_page ->
""
true ->
page_link(
index_path(opts, [conn, :index, transform_params(rummage, per_page, page_num, opts)]),
do: page_num
)
end
end)
end
defp next_page_link(conn, rummage, opts) do
paginate_params = rummage.paginate
page = paginate_params.page
per_page = paginate_params.per_page
max_page = paginate_params.max_page
label = opts[:next_label] || "Next"
case page >= max_page do
true ->
page_link("#", :disabled, do: label)
false ->
page_link(
index_path(opts, [conn, :index, transform_params(rummage, per_page, page + 1, opts)]),
do: label
)
end
end
defp last_page_link(conn, rummage, opts) do
paginate_params = rummage.paginate
page = paginate_params.page
per_page = paginate_params.per_page
# max_page_links = String.to_integer(paginate_params["max_page_links"] || "4")
max_page = paginate_params.max_page
label = opts[:last_label] || "Last"
case page >= max_page do
true ->
page_link("#", :disabled, do: label)
false ->
page_link(
index_path(opts, [conn, :index, transform_params(rummage, per_page, max_page, opts)]),
do: label
)
end
end
defp transform_params(rummage, per_page, page, opts)
defp transform_params(rummage, per_page, page, %{slugs: slugs, slugs_params: slugs_params}) do
rummage = %{
rummage: Map.put(rummage.params, "paginate", %{"per_page" => per_page, "page" => page})
}
slugs ++ Map.merge(rummage, slugs_params)
end
defp transform_params(rummage, per_page, page, _opts) do
%{rummage: Map.put(rummage.params, :paginate, %{per_page: per_page, page: page})}
end
defp index_path(opts, params) do
helpers = opts[:helpers]
path_function_name = String.to_atom("#{opts[:struct]}_path")
apply(helpers, path_function_name, params)
end
end