From dd3eb6669b352b28873c85c7b7bcb3a3c4d312b0 Mon Sep 17 00:00:00 2001 From: Jared Moody Date: Sun, 6 Mar 2022 23:23:18 -0800 Subject: [PATCH] Refactor Search Frontend Reduce the need for custom javascript by leveraging Turbo and HTML conventions: - By using a form, Turbo handles submission for us and fires events we can use to toggle the loading icon. - Use css to handle display of loading icon --- .../stylesheets/application.postcss.css | 1 + app/assets/stylesheets/components/search.css | 7 ++++ .../controllers/search_controller.js | 38 ++++++++----------- app/views/shared/_search_bar.html.erb | 23 ++++++----- test/system/search_test.rb | 4 +- 5 files changed, 40 insertions(+), 33 deletions(-) create mode 100644 app/assets/stylesheets/components/search.css diff --git a/app/assets/stylesheets/application.postcss.css b/app/assets/stylesheets/application.postcss.css index 909b6aea..9b93c449 100644 --- a/app/assets/stylesheets/application.postcss.css +++ b/app/assets/stylesheets/application.postcss.css @@ -43,6 +43,7 @@ @import 'components/nav.css'; @import 'components/action_bar.css'; @import 'components/table.css'; +@import 'components/search.css'; @import 'utilities/display.css'; @import 'utilities/spacing.css'; diff --git a/app/assets/stylesheets/components/search.css b/app/assets/stylesheets/components/search.css new file mode 100644 index 00000000..9cef806e --- /dev/null +++ b/app/assets/stylesheets/components/search.css @@ -0,0 +1,7 @@ +.c-search .c-loader { + display: none; +} + +.c-search.loading .c-loader { + display: revert; +} diff --git a/app/javascript/controllers/search_controller.js b/app/javascript/controllers/search_controller.js index f83fc256..bb8100a8 100644 --- a/app/javascript/controllers/search_controller.js +++ b/app/javascript/controllers/search_controller.js @@ -1,36 +1,30 @@ import { Controller } from '@hotwired/stimulus'; export default class extends Controller { - static targets = ['loader', 'input']; + static targets = ['input']; connect() { - this.inputTarget.value = this.inputTarget.getAttribute('value'); + this.moveCursorToEnd(); } - disconnect() { - this.loaderTarget.classList.add('u-display-none'); - this.inputTarget.value = ''; + moveCursorToEnd() { + const searchValueLength = this.inputTarget.value.length; + if (searchValueLength > 0) { + this.inputTarget.focus(); + this.inputTarget.setSelectionRange(searchValueLength, searchValueLength); + } } - query(event) { - const query = event.target.value.trim(); + submit(e) { + this.inputTarget.value = this.inputTarget.value.trim(); - if (event.key != 'Enter' || query == '') { return; } - - this.loaderTarget.classList.remove('u-display-none'); - const queryUrl = `/search${query ? `?query=${query}` : ''}`; - - Turbo.visit(queryUrl); - this._focusInput(); + if (this.inputTarget.value.length === 0) { + e.preventDefault(); + e.stopPropagation(); + } } - _focusInput() { - document.addEventListener('turbo:load', () => { - const searchElement = document.querySelector('#js-search-input'); - const searchValueLength = searchElement.value.length; - - searchElement.focus(); - searchElement.setSelectionRange(searchValueLength, searchValueLength); - }, { once: true }); + loading(e) { + this.element.classList.toggle('loading', e.type == 'turbo:submit-start'); } } diff --git a/app/views/shared/_search_bar.html.erb b/app/views/shared/_search_bar.html.erb index 8ed0b401..26a6a4f3 100644 --- a/app/views/shared/_search_bar.html.erb +++ b/app/views/shared/_search_bar.html.erb @@ -1,12 +1,17 @@ -
-
- <%= icon_tag 'search', size: 'large' %> -
- -
- <%= loader_tag size: 'small' %> -
-
+<%= form_tag search_path, method: :get, class: 'c-search c-input-group o-grid__item', + 'span@medium': '2-6', span: '3-5', + data: { action: 'turbo:submit-start->search#loading turbo:submit-end->search#loading search#submit', + controller: 'search' } do %> +
+ <%= icon_tag 'search', size: 'large' %> +
+ <%= text_field_tag 'query', params[:query], class: 'c-input', + data: { search_target: 'input', test_id: 'search_input' } %> +
+ <%= loader_tag size: 'small' %> +
+<% end %> +
<%= avatar_tag Current.user %> diff --git a/test/system/search_test.rb b/test/system/search_test.rb index 43d40b02..0c4d9a21 100644 --- a/test/system/search_test.rb +++ b/test/system/search_test.rb @@ -8,14 +8,14 @@ class SearchSystemTest < ApplicationSystemTestCase end test "show search results" do - fill_in "search_input", with: "artist" + fill_in "query", with: "artist" find(:test_id, "search_input").send_keys(:enter) assert_text('Search results for "artist"') end test "can not request search when query text is empty" do - fill_in "search_input", with: "" + fill_in "query", with: "" find(:test_id, "search_input").send_keys(:enter) assert_no_text('Search results for "artist"')