Last active
June 5, 2021 19:32
-
-
Save secretpray/51ed77da7da15321d5250faa3ef2fa5e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -------- model Recipe ----------- | |
| Before: Stimulus must be installed -> rails webpacker:install:stimulus (yarn add stimulus) | |
| 1) Gemfile: | |
| =========== | |
| gem 'pg_search' # По желанию (Optional) | |
| 2) touch app/views/shared/_search_form.html.erb | |
| ================================================ | |
| <%= form_with url: search_path, method: :get, class: 'd-flex', data: { action: "ajax:success->search#handleResults", "search-target" => "form" }, local: false do |form| %> | |
| <div> | |
| <%= form.text_field :search, data: { action: "input->search#search" }, | |
| autocomplete: "off", placeholder: 'Autocomplete search...', | |
| class: 'form-control me-2', id: 'autocomplete-input' %> | |
| </div> | |
| <% end %> | |
| 3) touch app/views/shared/_search_recipe.html.erb | |
| ================================================= | |
| <ul class="list-group"> | |
| <li class="list-group-item" role="option"> | |
| <%= link_to recipe.title, recipe, class: 'text-decoration-none text-primary' %> | |
| <%= link_to '#', class: 'autocomplete-close' do %> | |
| <span style="position: absolute; top: 3px; font-size: 20px;right: 10px;"> | |
| × | |
| </span> | |
| <% end %> | |
| </li> | |
| </ul> | |
| or with preview image item # По желанию (Optional) | |
| <ul class="list-group"> | |
| <li class="list-group-item" role="option"> | |
| <%= link_to image_preview(recipe, true), recipe %> | |
| | |
| <%= link_to recipe.title, recipe, class: 'text-decoration-none text-primary' %> | |
| <%= link_to '#', class: 'autocomplete-close' do %> | |
| <span style="position: absolute; top: 3px; font-size: 20px;right: 10px;"> | |
| × | |
| </span> | |
| <% end %> | |
| </li> | |
| </ul> | |
| module RecipesHelper | |
| def image_preview(recipe, small = nil) | |
| sized = small.nil? ? '200x200!' : '75x75!' | |
| if recipe.recipe_image.attached? | |
| image_tag recipe.recipe_image.variant(resize: sized).processed | |
| else | |
| image_tag("Default_image.png", size: sized) | |
| end | |
| end | |
| end | |
| 4) Add to app/views/shared/_navigation.html.erb | |
| =============================================== | |
| <% if is_active('dashboard','index') %> | |
| <li class="nav-item d-flex ms-5 align-items-start"> | |
| <div data-controller="search"> | |
| <%= render partial: "shared/search_form" %> | |
| <div data-search-target="results" id="results-dropdown" style="position: absolute;"> | |
| <% if @recipes&.any? %> | |
| <% @recipes.each do |recipe| %> | |
| <%= render partial: "shared/search_recipe", locals: { recipe: recipe } %> | |
| <% end %> | |
| <% end %> | |
| </div> | |
| </div> | |
| </li> | |
| <% end %> | |
| module ApplicationHelper | |
| # Navigation menu activa | |
| def is_active(controller, action) | |
| params[:action] == action && params[:controller] == controller ? "active" : nil | |
| end | |
| end | |
| 5) model Recipe # По желанию (Optional) only with gem 'pg_search | |
| ================================================================= | |
| pg_search_scope :global_search, against: [:title, :description], using: { tsearch: { prefix: true } } | |
| 6) routes.rb | |
| ============ | |
| get '/search', to: 'dashboard#search' | |
| 7) Dashboard Controller | |
| ====================== | |
| class DashboardController < ApplicationController | |
| def search | |
| if params[:search].present? && params[:search].size > 1 | |
| @recipes = Recipe.order(created_at: :desc).global_search(params[:search]).limit(5) | |
| end | |
| render layout: false | |
| end | |
| end | |
| 8) app/views/dashboard/search.html.erb | |
| ======================================= | |
| <% if @recipes&.any? %> | |
| <% @recipes.each do |recipe| %> | |
| <%= render partial: "shared/search_recipe", locals: { recipe: recipe } %> | |
| <% end %> | |
| <% end %> | |
| 9) Create in app/javascript/controllers: search_controller.js | |
| ============================================================= | |
| import { Controller } from "stimulus" | |
| export default class extends Controller { | |
| static targets = [ "results", "form" ] | |
| connect() { | |
| // console.log("Connected!") | |
| } | |
| search() { | |
| var inputAutocomplete = document.querySelector("#autocomplete-input") | |
| inputAutocomplete.addEventListener('keyup', (event) => { | |
| if (event.target.value.length > 1) { | |
| // wait for the user to stop typing before submitting the form | |
| clearTimeout(this.timeout) | |
| this.timeout = setTimeout(() => { | |
| Rails.fire(this.formTarget, 'submit') | |
| }, 200) | |
| } | |
| // clear droplist items if input set to blank | |
| if (event.target.value.length == 0) { | |
| var dropList = document.querySelector("#results-dropdown") | |
| if (dropList.size != 0) { dropList.innerText = '' } | |
| } | |
| }) | |
| } | |
| handleResults() { | |
| // debugger; | |
| const [data, status, xhr] = event.detail | |
| this.resultsTarget.innerHTML = xhr.response | |
| } | |
| } | |
| 10) add to app/javascript/packs/application.js | |
| ============================================== | |
| require("utilities/auto_hide") | |
| window.Rails = Rails | |
| 11) add app/javascript/utilities/auto_hide.js | |
| ============================================= | |
| document.addEventListener('turbolinks:load', function() { | |
| // Dismiss dropdown search list with button X | |
| var butttonAutoComplete = {} | |
| butttonAutoComplete = document.querySelector(".autocomplete-close") | |
| var dropList = {} | |
| dropList = document.querySelector("#results-dropdown") | |
| if (butttonAutoComplete) { | |
| butttonAutoComplete.addEventListener('click', () => { | |
| dropList.innerText = ''; | |
| }) | |
| } | |
| }) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment