Skip to content

Instantly share code, notes, and snippets.

@joshchernoff
Last active September 26, 2021 04:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joshchernoff/e8473ed01f31e01a2153c9b621ee529f to your computer and use it in GitHub Desktop.
Save joshchernoff/e8473ed01f31e01a2153c9b621ee529f to your computer and use it in GitHub Desktop.
Add pagination to your Phoenix LiveView project with Dissolver and live_patch https://github.com/MorphicPro/dissolver
# lib/my_app_web/live/post_live/index.ex
defmodule MyAppWeb.PostLive.Index do
use MyAppWeb, :live_view
alias MyApp.Blog
@impl true
def mount(_params, _session, socket) do
{:ok, socket}
end
@impl true
def handle_params(params, _url, socket) do
{:noreply, apply_action(socket, socket.assigns.live_action, params)}
end
defp apply_action(socket, :index, params) do
{posts, dissolver} = Blog.list_posts(params)
socket
|> assign(:page_title, "Listing Posts")
|> assign(dissolver: dissolver)
|> assign(posts: posts)
end
end
# lib/my_app_web/live/post_live/index.html.leex
<div class="container px-4 py-10 mx-auto">
<div class="grid gap-8 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
<%= for post <- @posts do %>
<div class="max-w-sm mx-auto overflow-hidden bg-white shadow-md">
<%= live_redirect to: Routes.post_show_path(@socket, :show, post) do %>
<img class="w-full" src="<%= post.thumb_img %>" alt="<%= post.title %>">
<% end %>
<div class="px-6 py-4">
<div class="mb-2 text-xs"><%= post.published_at %></div>
<div class="mb-2 text-xl font-bold">
<%= live_redirect post.title, to: Routes.post_show_path(@socket, :show, post), class: "hover:text-gray-600" %>
</div>
<div class="text-base text-gray-700 post-body">
<%= post.excerpt %>
</div>
</div>
</div>
<% end %>
</div>
</div>
<div class="container px-4 py-10 mx-auto">
<%= paginate @socket, @dissolver, &Routes.post_index_path/3, :index %>
</div>
# lib/my_app_web/dissolver/html/tailwind.ex
defmodule MyAppWeb.Dissolver.HTML.Tailwind do
@behaviour Dissolver.HTML.Theme
use Phoenix.HTML
import Phoenix.LiveView.Helpers
@moduledoc """
This is a theme to support Tailwind css.
https://tailwindcss.com/
"""
@impl Dissolver.HTML.Theme
def generate_links(page_list, additional_class) do
content_tag :div, class: build_html_class(additional_class), role: "pagination" do
for {label, _page, url, is_current} <- page_list do
live_patch("#{label}",
to: url,
class:
hide_for_mobile(is_current, label) <>
"text-sm px-3 py-2 mx-1 rounded-lg hover:bg-gray-700 hover:text-gray-200 " <>
if_active_class(is_current)
)
end
end
end
defp build_html_class(additional_class) do
String.trim("text-center pagination #{additional_class}")
end
defp if_active_class(true), do: "bg-gray-300"
defp if_active_class(_), do: ""
defp hide_for_mobile(false, page) when is_number(page), do: "hidden md:inline "
defp hide_for_mobile(_, _), do: ""
end
@joshchernoff
Copy link
Author

joshchernoff commented May 7, 2020

Screen Shot 2020-05-06 at 6 14 24 PM

@joshchernoff
Copy link
Author

Screen Shot 2020-05-06 at 6 17 18 PM

@joshchernoff
Copy link
Author

If you wanted to you could dynamically state which page you are on in the title.

https://gist.github.com/joshchernoff/e8473ed01f31e01a2153c9b621ee529f#file-index-ex-L22

|> assign(:page_title, "Listing Posts | Page: #{dissolver.page}")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment