Skip to content

Commit

Permalink
Add more classes to table elements
Browse files Browse the repository at this point in the history
  • Loading branch information
alanvardy committed Jul 30, 2024
1 parent 9d670db commit ace352d
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 47 deletions.
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unreleased

- User can add additional classes to table elements

## v0.6.5 (2024-06-18)
- Add `:query_modifier` option to allow dynamic altering of queries
- Update Elixir and Erlang versions
Expand All @@ -15,7 +17,7 @@
- Dependency updates and test fixes only

## v0.6.2 (2023-04-06)
- Rerelease to fix versioning issue
- Re-release to fix versioning issue

## v0.6.1 (2023-04-06)
- Fix issue with adding action buttons to table
Expand All @@ -31,7 +33,7 @@

## v0.5.5 (2022-07-23)

- Bugfix for default formatter. Previously, it would attempt to_string on all values passing through which breaks `:safe` tuples.
- Bug fix for default formatter. Previously, it would attempt to_string on all values passing through which breaks `:safe` tuples.
- Support live routes
- Increase test coverage
- Fix CodeCov badge link
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ Note that if you are navigating to the live table using [Phoenix LiveView live_s
- `text: Exzeitable.Text.Default` The translation that appears on the table, defaults to English.
- `assigns: %{}` Passes additional assigns to socket.assigns. Keep your payload small!
- `query_modifier: {MyModule, :my_function}` Passes the query to MyModule.my_function/2, where query can then be dynamically altered before being returned. Arguments are the query, and the `Exzeitable.Params` struct, which is how Exzeitable stores state. Return value is the query.
- `html_classes` Allows the user to add additional HTML classes to elements. Is a list of 2-element tuples where the first element is a string representing the default class (or classes) and the second element is a string representing the classes to be added. I.e. if the default class is `exz-pagination-ul` then you can append `p-5` to it by adding `html_classes: [{"exz-pagination-ul", "p-5"}]`. This can make styling the table with tailwind or bootstrap much easier.

```elixir
defmodule MyApp.MyModule do
Expand Down
20 changes: 17 additions & 3 deletions lib/exzeitable/html.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@ defmodule Exzeitable.HTML do
top_navigation =
div_wrap(
[
div_wrap([top_pagination, new_button, show_hide_fields], "exz-pagination-wrapper"),
div_wrap(
[top_pagination, new_button, show_hide_fields],
class(params, "exz-pagination-wrapper")
),
search_box
],
"exz-row"
class(params, "exz-row")
)

content_tag(
Expand All @@ -40,11 +43,22 @@ defmodule Exzeitable.HTML do
bottom_buttons,
bottom_pagination
],
class: "outer-wrapper",
class: class(params, "outer-wrapper"),
onclick: ""
)
end

def class(%Params{html_classes: nil}, class) do
class
end

def class(%Params{html_classes: html_classes}, class) do
case Enum.find(html_classes, &(elem(&1, 0) === class)) do
{_, additional_classes} -> "#{class} #{additional_classes}"
nil -> class
end
end

defp div_wrap(content, class \\ "") do
content_tag(:div, content, class: class)
end
Expand Down
10 changes: 6 additions & 4 deletions lib/exzeitable/html/action_button.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
defmodule Exzeitable.HTML.ActionButton do
alias Exzeitable.HTML

@moduledoc """
For the actions buttons such as :new, :edit etc, as well as custom buttons.
Expand Down Expand Up @@ -148,27 +150,27 @@ defmodule Exzeitable.HTML.ActionButton do
defp html(route, :new, %Params{} = params) do
params
|> Text.text(:new)
|> Link.link(to: route, class: "exz-action-new")
|> Link.link(to: route, class: HTML.class(params, "exz-action-new"))
end

defp html(route, :show, %Params{} = params) do
params
|> Text.text(:show)
|> Link.link(to: route, class: "exz-action-show")
|> Link.link(to: route, class: HTML.class(params, "exz-action-show"))
end

defp html(route, :edit, %Params{} = params) do
params
|> Text.text(:edit)
|> Link.link(to: route, class: "exz-action-edit")
|> Link.link(to: route, class: HTML.class(params, "exz-action-edit"))
end

defp html(route, :delete, %Params{csrf_token: csrf_token} = params) do
params
|> Text.text(:delete)
|> Link.link(
to: route,
class: "exz-action-delete",
class: HTML.class(params, "exz-action-delete"),
method: :delete,
"data-confirm": Text.text(params, :confirm_action),
csrf_token: csrf_token
Expand Down
43 changes: 23 additions & 20 deletions lib/exzeitable/html/pagination.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule Exzeitable.HTML.Pagination do
"""

alias Exzeitable.HTML.Helpers
alias Exzeitable.{Params, Text}
alias Exzeitable.{Params, Text, HTML}

@type name :: :next | :previous | :dots | pos_integer
@type page :: pos_integer
Expand All @@ -19,8 +19,8 @@ defmodule Exzeitable.HTML.Pagination do
next_button = paginate_button(params, :next, page, pages)

([previous_button] ++ numbered_buttons ++ [next_button])
|> Helpers.tag(:ul, class: "exz-pagination-ul")
|> Helpers.tag(:nav, class: "exz-pagination-nav")
|> Helpers.tag(:ul, class: HTML.class(params, "exz-pagination-ul"))
|> Helpers.tag(:nav, class: HTML.class(params, "exz-pagination-nav"))
end

# Handle the case where there is only a single page, just gives us some disabled buttons
Expand All @@ -45,60 +45,63 @@ defmodule Exzeitable.HTML.Pagination do
defp paginate_button(%Params{} = params, :next, page, page) do
params
|> Text.text(:next)
|> Helpers.tag(:a, class: "exz-pagination-a", tabindex: "-1")
|> Helpers.tag(:li, class: "exz-pagination-li-disabled")
|> Helpers.tag(:a, class: HTML.class(params, "exz-pagination-a"), tabindex: "-1")
|> Helpers.tag(:li, class: HTML.class(params, "exz-pagination-li-disabled"))
end

defp paginate_button(%Params{} = params, :previous, 1, _pages) do
params
|> Text.text(:previous)
|> Helpers.tag(:a, class: "exz-pagination-a", tabindex: "-1")
|> Helpers.tag(:li, class: "exz-pagination-li-disabled")
|> Helpers.tag(:a, class: HTML.class(params, "exz-pagination-a"), tabindex: "-1")
|> Helpers.tag(:li, class: HTML.class(params, "exz-pagination-li-disabled"))
end

defp paginate_button(_params, :dots, _page, _pages) do
defp paginate_button(params, :dots, _page, _pages) do
"...."
|> Helpers.tag(:a, class: "exz-pagination-a exz-pagination-width", tabindex: "-1")
|> Helpers.tag(:li, class: "exz-pagination-li-disabled")
|> Helpers.tag(:a,
class: HTML.class(params, "exz-pagination-a exz-pagination-width"),
tabindex: "-1"
)
|> Helpers.tag(:li, class: HTML.class(params, "exz-pagination-li-disabled"))
end

defp paginate_button(%Params{} = params, :next, page, _pages) do
params
|> Text.text(:next)
|> Helpers.tag(:a,
class: "exz-pagination-a",
class: HTML.class(params, "exz-pagination-a"),
style: "cursor: pointer",
"phx-click": "change_page",
"phx-value-page": page + 1
)
|> Helpers.tag(:li, class: "exz-pagination-li")
|> Helpers.tag(:li, class: HTML.class(params, "exz-pagination-li"))
end

defp paginate_button(%Params{} = params, :previous, page, _pages) do
params
|> Text.text(:previous)
|> Helpers.tag(:a,
class: "exz-pagination-a",
class: HTML.class(params, "exz-pagination-a"),
style: "cursor: pointer",
"phx-click": "change_page",
"phx-value-page": page - 1
)
|> Helpers.tag(:li, class: "exz-pagination-li")
|> Helpers.tag(:li, class: HTML.class(params, "exz-pagination-li"))
end

defp paginate_button(_params, page, page, _pages) when is_integer(page) do
Helpers.tag(page, :a, class: "exz-pagination-a exz-pagination-width")
|> Helpers.tag(:li, class: "exz-pagination-li-active")
defp paginate_button(params, page, page, _pages) when is_integer(page) do
Helpers.tag(page, :a, class: HTML.class(params, "exz-pagination-a exz-pagination-width"))
|> Helpers.tag(:li, class: HTML.class(params, "exz-pagination-li-active"))
end

defp paginate_button(_params, page, _page, _pages) when is_integer(page) do
defp paginate_button(params, page, _page, _pages) when is_integer(page) do
Helpers.tag(page, :a,
class: "exz-pagination-a exz-pagination-width",
class: HTML.class(params, "exz-pagination-a exz-pagination-width"),
style: "cursor: pointer",
"phx-click": "change_page",
"phx-value-page": page
)
|> Helpers.tag(:li, class: "exz-pagination-li")
|> Helpers.tag(:li, class: HTML.class(params, "exz-pagination-li"))
end

@doc "Selects the page buttons we need for pagination"
Expand Down
16 changes: 8 additions & 8 deletions lib/exzeitable/html/search.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ defmodule Exzeitable.HTML.Search do
@moduledoc "Build the search field part of the HTML"

alias Exzeitable.HTML.Helpers
alias Exzeitable.{Params, Text}
alias Exzeitable.{Params, Text, HTML}
alias PhoenixHTMLHelpers.Form

@doc "Returns the HTML search form"
Expand All @@ -15,31 +15,31 @@ defmodule Exzeitable.HTML.Search do
# onkeypress to disable enter key in search field
[
phx_change: :search,
class: "exz-search-form",
class: HTML.class(params, "exz-search-form"),
onkeypress: "return event.keyCode != 13;"
],
fn f ->
[
Form.text_input(f, :search,
placeholder: Text.text(params, :search),
class: "exz-search-field",
class: HTML.class(params, "exz-search-field"),
phx_debounce: debounce
),
counter(params)
]
|> Helpers.tag(:div, class: "exz-search-field-wrapper")
|> Helpers.tag(:div, class: HTML.class(params, "exz-search-field-wrapper"))
end
)
|> Helpers.tag(:div, class: "exz-search-wrapper")
|> Helpers.tag(:div, class: HTML.class(params, "exz-search-wrapper"))
else
{:safe, [""]}
end
end

defp counter(%Params{count: count}) do
defp counter(%Params{count: count} = params) do
count
|> Helpers.tag(:span, class: "exz-counter-field")
|> Helpers.tag(:div, class: "exz-counter-field-wrapper")
|> Helpers.tag(:span, class: HTML.class(params, "exz-counter-field"))
|> Helpers.tag(:div, class: HTML.class(params, "exz-counter-field-wrapper"))
end

# Returns true if any of the fields have search enabled
Expand Down
8 changes: 4 additions & 4 deletions lib/exzeitable/html/show_button.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule Exzeitable.HTML.ShowButton do
@moduledoc "Show buttons and the buttons that toggle their visibility"
alias Exzeitable.HTML.{Filter, Format, Helpers}
alias Exzeitable.{Params, Text}
alias Exzeitable.{Params, Text, HTML}

@doc "Returns HTML for all the show column buttons that should be visible"
@spec show_buttons(Params.t()) :: [{:safe, iolist}]
Expand All @@ -22,7 +22,7 @@ defmodule Exzeitable.HTML.ShowButton do
params
|> Text.text(:show_field, name)
|> Helpers.tag(:a,
class: "exz-show-button",
class: HTML.class(params, "exz-show-button"),
"phx-click": "show_column",
"phx-value-column": key
)
Expand All @@ -38,7 +38,7 @@ defmodule Exzeitable.HTML.ShowButton do
params
|> Text.text(:hide_field_buttons)
|> Helpers.tag(:a,
class: "exz-info-button",
class: HTML.class(params, "exz-info-button"),
"phx-click": "hide_buttons"
)
end
Expand All @@ -47,7 +47,7 @@ defmodule Exzeitable.HTML.ShowButton do
params
|> Text.text(:show_field_buttons)
|> Helpers.tag(:a,
class: "exz-info-button",
class: HTML.class(params, "exz-info-button"),
"phx-click": "show_buttons"
)
end
Expand Down
12 changes: 6 additions & 6 deletions lib/exzeitable/html/table.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
defmodule Exzeitable.HTML.Table do
@moduledoc "Builds the table part of the HTML"
alias Exzeitable.{Params, Text}
alias Exzeitable.{Params, Text, HTML}
alias Exzeitable.HTML.{ActionButton, Filter, Format, Helpers}
alias PhoenixHTMLHelpers.Link

Expand All @@ -20,9 +20,9 @@ defmodule Exzeitable.HTML.Table do
|> Helpers.tag(:tbody, [])

[head, body]
|> Helpers.tag(:table, class: "exz-table")
|> Helpers.tag(:table, class: HTML.class(params, "exz-table"))
|> maybe_nothing_found(params)
|> Helpers.tag(:div, class: "exz-table-wrapper")
|> Helpers.tag(:div, class: HTML.class(params, "exz-table-wrapper"))
end

@spec add_actions_header(keyword, map) :: keyword
Expand Down Expand Up @@ -71,7 +71,7 @@ defmodule Exzeitable.HTML.Table do
params
|> Text.text(:hide)
|> Helpers.tag(:a,
class: "exz-hide-link",
class: HTML.class(params, "exz-hide-link"),
"phx-click": "hide_column",
"phx-value-column": key
)
Expand All @@ -93,7 +93,7 @@ defmodule Exzeitable.HTML.Table do

Link.link(label,
to: "",
class: "exz-sort-link",
class: HTML.class(params, "exz-sort-link"),
"phx-click": "sort_column",
"phx-value-column": key
)
Expand All @@ -103,7 +103,7 @@ defmodule Exzeitable.HTML.Table do
nothing_found =
params
|> Text.text(:nothing_found)
|> Helpers.tag(:div, class: "exz-nothing-found")
|> Helpers.tag(:div, class: HTML.class(params, "exz-nothing-found"))

[content, nothing_found]
end
Expand Down
2 changes: 2 additions & 0 deletions lib/exzeitable/params.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ defmodule Exzeitable.Params do
csrf_token: String.t(),
# optional
order: [{:asc | :desc, column}] | nil,
html_classes: Keyword.t(String.t()) | nil,
parent: struct | nil,
belongs_to: atom | nil,
page: pos_integer,
Expand Down Expand Up @@ -55,6 +56,7 @@ defmodule Exzeitable.Params do
:order,
:parent,
:belongs_to,
:html_classes,
page: 1,
count: 0,
list: [],
Expand Down
7 changes: 7 additions & 0 deletions lib/test_web/live_tables/post_table.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ defmodule TestWeb.PostTable do
routes: Routes,
path: :post_path,
fields: [title: [], content: []],
html_classes: [
{"exz-pagination-wrapper", "text-lg test-black-200"}
],
query: from(p in Post),
action_buttons: [:show, :edit, :custom_button],
refresh: 5000
Expand All @@ -16,3 +19,7 @@ defmodule TestWeb.PostTable do

def custom_button(_socket, _entry, _csrf_token), do: "CUSTOM BUTTON"
end

# Goals
# Identify all the places to add additional classes
# Validate that all or no classes are present

0 comments on commit ace352d

Please sign in to comment.