Rummage.Phoenix
is a support framework for Phoenix
that can be used to manipulate Phoenix
collections and Ecto
models with Search, Sort and Paginate operations.
It accomplishes the above operations by using Rummage.Ecto
, to paginate Ecto
queries and adds Phoenix and HTML
support to views and controllers. For information on how to configure Rummage.Ecto
visit
this page.
The best part about rummage is that all the three operations: Search
, Sort
and Paginate
integrate seamlessly and
can be configured separately. To check out their seamless integration, please check the information below.
NOTE: Rummage
is not like Ransack
, and doesn't intend to be either. It doesn't add functions based on search params.
If you'd like to have that for a model, you can always configure Rummage
to use your Search
module for that model. This
is why Rummage has been made configurable.
Search, Sort and Paginate seamlessly in Phoenix!
This is available in Hex, the package can be installed as:
-
Add
rummage_phoenix
to your list of dependencies inmix.exs
:def deps do [ {:rummage_phoenix, "~> 1.2.0"} ] end
- Using Rummage.Phoenix 2
- Using the Rummage Search hook
- Using the Rummage Sort hook
- Writing a Custom Rummage.Ecto Hook
- Writing a Custom Rummage.Phoenix HTML helper
- Using Rummage with other Libraries: Kerosene
- Using Rummage with other Libraries: Scrivener
Rumamge.Phoenix
can be configured globally with a default_per_page
value (which can be overriden for a model).
This is NOT the preferred way to set default_per_page
as it might lead to conflicts. It is recommended to
do it per model as show below in the Initial Setup section. If you want to set default_per_page
for all the models, add it to model
function in web.ex
-
Add
rummage_phoenix
config to your list of configs indev.exs
:config :rummage_phoenix, Rummage.Phoenix, default_per_page: 5
Usage (The screenshots correspond to version 0.6.0, soon there will be screenshots for version 1.0.0)
- Use
Rummage.Controller
in to controller module:
defmodule MyApp.ProductController do
use MyApp.Web, :controller
use Rummage.Phoenix.Controller
# More code below....
end
- Change the
index
action in the controller:
def index(conn, params) do
{query, rummage} = Product
|> Rummage.Ecto.rummage(params["rummage"])
products = Repo.all(query)
render conn, "index.html",
products: products,
rummage: rummage
end
- if using Search feature, define a
search
path in therouter.ex
(no need to define the action):
scope "/", MyApp do
pipe_through :browser # Use the default browser stack
get "/", PageController, :index
resources "/products", ProductController
end
Doing this itself will allow you to search, sort and paginate by updating params
on the request.
Please check the screenshots below for details
- Use
Rummage.View
in to a view module:
defmodule MyApp.ProductView do
use MyApp.Web, :view
use Rummage.Phoenix.View
# More code below...
end
Note: If you get a "MyApp.Router.Helpers is not available" exception, you can provide your router with:
defmodule MyApp.ProductView do
use MyApp.Web, :view
use Rummage.Phoenix.View, helpers: MyApp.Web.Router.Helpers
# More code below...
end
or through the config:
config :rummage_phoenix, Rummage.Phoenix, [
default_helpers: MyApp.Web.Router.Helpers,
]
Note: If the path helper name is incorrect, you can specify it with:
defmodule MyApp.ProductView do
use MyApp.Web, :view
use Rummage.Phoenix.View, struct: "special_product" # will become special_product_path
# More code below...
end
Add this at the bottom of index.html.eex
to render Rummage
pagination links (Make sure that you
pass rummage
to the views from the index
action in the controller) :
<%= pagination_link(@conn, @rummage) %>
Reload and this is how your page should look:
Replace table headers on the index.html.eex
with sort links (Make sure that the headers are actual columns in the
table in the database.)
Replace this:
<th>Name</th>
<th>Price</th>
<th>Category</th>
With:
<th><%= sort_link @conn, @rummage, [field: :name, ci: true] %></th>
<th><%= sort_link @conn, @rummage, [field: :price] %></th>
OR for Sort by associations:
<th><%= sort_link @conn, @rummage, [field: :name, name: "Category Name", assoc: ["category"]] %></th>
Reload and this is how your page should look with sortable links instead of just table headers:
NOTE: Currently working on adding better elements to the views, soon the text arrow in the sort links will be replaced by an icon
Add a search form in the index.html.eex
with searchable fields:
<%= search_form(@conn, @rummage, [fields:
[
name: %{label: "Search by Product Name", search_type: "ilike"},
price: %{label: "Search by Price", search_type: "eq"},
], button_class: "btn",
]) %>
OR for Search by associations:
<%= search_form(@conn, @rummage, [fields:
[
name: %{label: "Search by Category Name", search_type: "ilike", assoc: ["category"]}
], button_class: "btn",
]) %>
Reload and your page should look somewhat like this:
The best part about Rummage
is that all the three hooks/operations integrate seamlessly without affecting each other's functionality
and therefore, you have a page looking somewhat like this:
- Default pagination:
- Custom pagination params: