From 8c7482c1d76c0f662ddb3f7b071cea5d7517815e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=B6hm?= Date: Sun, 31 May 2026 23:34:57 +0200 Subject: [PATCH] Changed item#_form input user/room --- .../controllers/autocomplete_controller.js | 65 +++++++++++++++ app/views/items/_form.html.erb | 79 ++++++++++++------- 2 files changed, 114 insertions(+), 30 deletions(-) create mode 100644 app/javascript/controllers/autocomplete_controller.js diff --git a/app/javascript/controllers/autocomplete_controller.js b/app/javascript/controllers/autocomplete_controller.js new file mode 100644 index 0000000..d6a0f5c --- /dev/null +++ b/app/javascript/controllers/autocomplete_controller.js @@ -0,0 +1,65 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + static targets = ["input", "results", "item"] + + connect() { + // Schließt die Liste, wenn man irgendwo außerhalb hinklickt + this.closeHandler = (e) => { + if (!this.element.contains(e.target)) { + this.hideResults() + } + } + document.addEventListener("click", this.closeHandler) + } + + disconnect() { + document.removeEventListener("click", this.closeHandler) + } + + // Wird aufgerufen, wenn der Nutzer tippt (input-Event) + filter() { + const filterValue = this.inputTarget.value.toLowerCase().trim() + + if (filterValue === "") { + this.showAll() + return + } + + this.showResults() + let hasMatches = false + + this.itemTargets.forEach(item => { + const text = item.textContent.toLowerCase() + if (text.includes(filterValue)) { + item.classList.remove("hidden") + hasMatches = true + } else { + item.classList.add("hidden") + } + }) + + // Falls gar nichts gefunden wird, blenden wir die Liste aus + if (!hasMatches) this.hideResults() + } + + // Ein Klick auf einen Eintrag wählt ihn aus + select(event) { + const value = event.currentTarget.dataset.value + this.inputTarget.value = value + this.hideResults() + } + + showResults() { + this.resultsTarget.classList.remove("hidden") + } + + hideResults() { + this.resultsTarget.classList.add("hidden") + } + + showAll() { + this.showResults() + this.itemTargets.forEach(item => item.classList.remove("hidden")) + } +} diff --git a/app/views/items/_form.html.erb b/app/views/items/_form.html.erb index 2220d1b..5d039e8 100644 --- a/app/views/items/_form.html.erb +++ b/app/views/items/_form.html.erb @@ -88,7 +88,7 @@ Item.conditions.keys.map { |cond| [Item.human_attribute_name("conditions.#{cond}"), cond] }, {}, class: "py-2.5 px-3 block w-full border border-gray-300 rounded-lg text-sm bg-gray-50/50 focus:border-blue-500 focus:ring-blue-500 appearance-none pr-10" %> - +
@@ -103,7 +103,7 @@
- + <%= turbo_frame_tag "item_assignment_frame" do %> <% current_type = if item.user_id.present? @@ -122,67 +122,85 @@ class: "py-2 px-3 text-xs font-medium rounded-md text-center transition flex items-center justify-center gap-1 #{type == 'storage' ? 'bg-white text-blue-600 shadow-sm font-semibold' : 'text-gray-600 hover:text-gray-900'}" do %> 📦 Lager <% end %> - + <%= link_to item.new_record? ? new_item_path(assignment_type: "user") : edit_item_path(item, assignment_type: "user"), class: "py-2 px-3 text-xs font-medium rounded-md text-center transition flex items-center justify-center gap-1 #{type == 'user' ? 'bg-white text-blue-600 shadow-sm font-semibold' : 'text-gray-600 hover:text-gray-900'}" do %> 👤 Mitarbeiter <% end %> - + <%= link_to item.new_record? ? new_item_path(assignment_type: "room") : edit_item_path(item, assignment_type: "room"), class: "py-2 px-3 text-xs font-medium rounded-md text-center transition flex items-center justify-center gap-1 #{type == 'room' ? 'bg-white text-blue-600 shadow-sm font-semibold' : 'text-gray-600 hover:text-gray-900'}" do %> 📍 Raum <% end %>
- +
<% if type == "user" %> - - - -
- + + + + +
- - + placeholder="Tippe den Namen ein..." + autocomplete="off"> + + +
- + <% elsif type == "room" %> - - + -
- + + +
- - + placeholder="Tippe die Raumnummer ein..." + autocomplete="off"> + + +
- + <% else %> -
@@ -190,6 +208,7 @@
<% end %>
+ <% end %>