Skip to content

Commit

Permalink
Add Turbo for live search in ui/table component
Browse files Browse the repository at this point in the history
This enhancement enables live search functionality in the products
list table, allowing users to search for products without reloading
the page.
  • Loading branch information
rainerdema committed Jul 26, 2023
1 parent 7f04516 commit 3b77454
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 47 deletions.
1 change: 1 addition & 0 deletions admin/app/components/solidus_admin/base_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module SolidusAdmin
# BaseComponent is the base class for all components in Solidus Admin.
class BaseComponent < ViewComponent::Base
include SolidusAdmin::ContainerHelper
include Turbo::FramesHelper

# Renders a remixincon svg.
#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
search_page_url: search_page_url,
previous_page_url: previous_page_url,
next_page_url: next_page_url,
turbo_frame_id: 'products-list',
batch_actions: [
{
display_name: t('.batch_actions.delete'),
Expand Down
91 changes: 47 additions & 44 deletions admin/app/components/solidus_admin/ui/table/component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -31,60 +31,63 @@
</div>
<% end %>
<table class="table-fixed w-full border-collapse">
<colgroup>
<% @columns.each do |column| %>
<col class="<%= column.class_name %>">
<% end %>
</colgroup>

<thead
class="bg-gray-15 text-gray-700 text-left text-small"
data-<%= stimulus_id %>-target="defaultHeader"
>
<tr>
<%= turbo_frame_tag @turbo_frame_id do %>
<table class="table-fixed w-full border-collapse">
<colgroup>
<% @columns.each do |column| %>
<%= render_header_cell(column.header) %>
<col class="<%= column.class_name %>">
<% end %>
</tr>
</thead>
</colgroup>

<% if @batch_actions %>
<thead
data-<%= stimulus_id %>-target="batchHeader"
class="bg-white color-black text-xs leading-none text-left"
class="bg-gray-15 text-gray-700 text-left text-small"
data-<%= stimulus_id %>-target="defaultHeader"
>
<tr>
<%= render_header_cell(selectable_column.header) %>
<%= render_header_cell(content_tag(:div, safe_join([
content_tag(:span, "0", "data-#{stimulus_id}-target": "selectedRowsCount"),
" #{t('.rows_selected')}.",
])), colspan: @columns.count - 1) %>
</div>
</thead>
<% end %>

<tbody class="bg-white text-3.5 line-[150%] text-black">
<% @rows.each do |row| %>
<tr class="border-b border-gray-100">
<% @columns.each do |column| %>
<%= render_data_cell(column.data, row) %>
<%= render_header_cell(column.header) %>
<% end %>
</tr>
<% end %>
</thead>

<% if @rows.empty? && @model_class %>
<tr>
<td
colspan="<%= @columns.size %>"
class="text-center py-4 text-3.5 line-[150%] text-black bg-white"
>
<%= t('.no_resources_found', resources: @model_class.model_name.human.pluralize) %>
</td>
</tr>
<% if @batch_actions %>
<thead
data-<%= stimulus_id %>-target="batchHeader"
class="bg-white color-black text-xs leading-none text-left"
hidden
>
<tr>
<%= render_header_cell(selectable_column.header) %>
<%= render_header_cell(content_tag(:div, safe_join([
content_tag(:span, "0", "data-#{stimulus_id}-target": "selectedRowsCount"),
" #{t('.rows_selected')}.",
])), colspan: @columns.count - 1) %>
</div>
</thead>
<% end %>
</tbody>

<%= render_table_footer %>
</table>
<tbody class="bg-white text-3.5 line-[150%] text-black">
<% @rows.each do |row| %>
<tr class="border-b border-gray-100">
<% @columns.each do |column| %>
<%= render_data_cell(column.data, row) %>
<% end %>
</tr>
<% end %>
<% if @rows.empty? && @model_class %>
<tr>
<td
colspan="<%= @columns.size %>"
class="text-center py-4 text-3.5 line-[150%] text-black bg-white"
>
<%= t('.no_resources_found', resources: @model_class.model_name.human.pluralize) %>
</td>
</tr>
<% end %>
</tbody>

<%= render_table_footer %>
</table>
<% end %>
</div>
7 changes: 7 additions & 0 deletions admin/app/components/solidus_admin/ui/table/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ export default class extends Controller {
this.checkField()
}

search() {
clearTimeout(this.timeout)
this.timeout = setTimeout(() => {
this.searchFormTarget.requestSubmit()
}, 200)
}

clearField() {
this.searchFieldTarget.value = ''
this.searchFieldTarget.closest('form').submit()
Expand Down
9 changes: 9 additions & 0 deletions admin/app/components/solidus_admin/ui/table/component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class SolidusAdmin::UI::Table::Component < SolidusAdmin::BaseComponent
# @param search_page_url [String] The base URL for searching.
# @param previous_page_url [String] The URL for the previous page.
# @param next_page_url [String] The URL for the next page.
# @param turbo_frame_id [String] The ID for the Turbo frame.
#
# @param columns [Array<Hash>] The array of column definitions.
# @option columns [Symbol|Proc|#to_s] :header The column header.
Expand All @@ -26,6 +27,7 @@ def initialize(
rows:,
search_key:,
search_page_url:,
turbo_frame_id:,
previous_page_url: nil,
next_page_url: nil,
columns: [],
Expand All @@ -43,6 +45,7 @@ def initialize(
@search_page_url = search_page_url
@previous_page_url = previous_page_url
@next_page_url = next_page_url
@turbo_frame_id = turbo_frame_id

@pagination_component = pagination_component
@checkbox_componnent = checkbox_componnent
Expand Down Expand Up @@ -145,6 +148,8 @@ def search_form_options
method: :get,
class: "h-14 p-2 bg-white border-b border-gray-10 relative hidden",
data: {
turbo_frame: @turbo_frame_id,
turbo_action: "advance",
"#{stimulus_id}_target": "searchForm"
}
}
Expand All @@ -155,6 +160,9 @@ def search_field_options
class: "border-2 border-gray-100 bg-white h-10 px-10 rounded-lg text-sm focus:outline-none flex-grow",
placeholder: "Search",
data: {
turbo_frame: @turbo_frame_id,
turbo_action: "advance",
action: "input->#{stimulus_id}#search",
"#{stimulus_id}_target": "searchField"
}
}
Expand Down Expand Up @@ -241,6 +249,7 @@ def render_pagination_component
@pagination_component.new(
previous_page_url: @previous_page_url,
next_page_url: @next_page_url,
turbo_frame_id: @turbo_frame_id
).render_in(self)
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<ul class="flex items-center">
<li>
<% if @previous_page_url %>
<%= link_to @previous_page_url, class: link_classes(rounded: :left) do %>
<%= link_to @previous_page_url, class: link_classes(rounded: :left), data: { turbo_action: 'replace', turbo_frame: @turbo_frame_id } do %>
<%= icon_tag("arrow-left-s-line", class: "w-5 h-5") %>
<% end %>
<% else %>
Expand All @@ -15,7 +15,7 @@

<li>
<% if @next_page_url %>
<%= link_to @next_page_url, class: link_classes(rounded: :right) do %>
<%= link_to @next_page_url, class: link_classes(rounded: :right), data: { turbo_action: 'replace', turbo_frame: @turbo_frame_id } do %>
<%= icon_tag("arrow-right-s-line", class: "w-5 h-5") %>
<% end %>
<% else %>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
class SolidusAdmin::UI::Table::Pagination::Component < SolidusAdmin::BaseComponent
# @param previous_page_url [String] The URL for the previous page.
# @param next_page_url [String] The URL for the next page.
def initialize(previous_page_url: nil, next_page_url: nil)
# @param turbo_frame_id [String] The ID for the Turbo frame.
def initialize(turbo_frame_id:, previous_page_url: nil, next_page_url: nil)
@previous_page_url = previous_page_url
@next_page_url = next_page_url
@turbo_frame_id = turbo_frame_id
end

def link_classes(rounded: nil)
Expand Down

0 comments on commit 3b77454

Please sign in to comment.