From 23e2d284880193eb392977a6949d88d002f4bb28 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Bellet Date: Tue, 27 Sep 2022 14:55:20 +0200 Subject: [PATCH] Implements the filter options feature --- .../multiple_checked_select_component.rb | 3 +- ...ultiple_checked_select_component.html.haml | 5 +++- .../multiple_checked_select_controller.js | 16 ++++++++++- app/webpacker/css/admin/dropdown.scss | 28 +++++++++++++++++++ 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/app/components/multiple_checked_select_component.rb b/app/components/multiple_checked_select_component.rb index e452625169..153a629742 100644 --- a/app/components/multiple_checked_select_component.rb +++ b/app/components/multiple_checked_select_component.rb @@ -1,8 +1,9 @@ # frozen_string_literal: true class MultipleCheckedSelectComponent < ViewComponent::Base - def initialize(name:, options:, selected:) + def initialize(name:, options:, selected:, filter_placeholder: "Filter options") @name = name + @filter_placeholder = filter_placeholder @options = options @selected = selected.map(&:to_sym) end diff --git a/app/components/multiple_checked_select_component/multiple_checked_select_component.html.haml b/app/components/multiple_checked_select_component/multiple_checked_select_component.html.haml index 11464fbb1b..ae15d26f70 100644 --- a/app/components/multiple_checked_select_component/multiple_checked_select_component.html.haml +++ b/app/components/multiple_checked_select_component/multiple_checked_select_component.html.haml @@ -4,9 +4,12 @@ = "  #{t('admin.columns')}".html_safe %span{ class: "icon-caret-down", "data-multiple-checked-select-target": "caret" } %div.menu{ class: "hidden", "data-multiple-checked-select-target": "options" } + %div.filter + %input{ type: "text", "data-multiple-checked-select-target": "filter", placeholder: @filter_placeholder } + %hr - @options.each do |option| - classes = @selected.include?(option[1]) ? "selected" : "" - %div.menu_item{ class: classes, "data-multiple-checked-select-target": "option", "data-value": option[1] } + %div.menu_item{ class: classes, "data-multiple-checked-select-target": "option", "data-value": option[1], "data-label": option[0] } %span.check %span.name{id: option[1]} = option[0] diff --git a/app/webpacker/controllers/multiple_checked_select_controller.js b/app/webpacker/controllers/multiple_checked_select_controller.js index 5dde603d1d..ddf52ff868 100644 --- a/app/webpacker/controllers/multiple_checked_select_controller.js +++ b/app/webpacker/controllers/multiple_checked_select_controller.js @@ -1,7 +1,7 @@ import { Controller } from "stimulus"; export default class extends Controller { - static targets = ["button", "caret", "options", "option", "inputs"]; + static targets = ["button", "caret", "options", "option", "inputs", "filter"]; static values = { inputName: String }; connect() { @@ -13,12 +13,26 @@ export default class extends Controller { }); this.buildInputs(); document.addEventListener("click", this.closeOptions); + this.filterTarget.addEventListener("input", this.filterOptions); } disconnect() { document.removeEventListener("click", this.closeOptions); } + // private methods + + filterOptions = (e) => { + const filter = e.target.value.toLowerCase(); + this.optionTargets.forEach((option) => { + if (option.dataset["label"].toLowerCase().includes(filter)) { + option.classList.remove("hidden"); + } else { + option.classList.add("hidden"); + } + }); + }; + toggleOptions = () => { this.optionsTarget.classList.toggle("hidden"); this.caretTarget.classList.toggle("icon-caret-down"); diff --git a/app/webpacker/css/admin/dropdown.scss b/app/webpacker/css/admin/dropdown.scss index e5e001d362..6547ae6b00 100644 --- a/app/webpacker/css/admin/dropdown.scss +++ b/app/webpacker/css/admin/dropdown.scss @@ -99,6 +99,30 @@ z-index: 100; white-space: nowrap; + .filter { + padding-left: 5px; + padding-right: 5px; + position: relative; + + > input[type="text"] { + border: 1px solid rgba(18, 18, 18, 0.1); + width: 100%; + padding-left: 30px; + padding-top: 10px; + padding-bottom: 10px; + font-size: 13px; + color:#454545; + } + + &:after { + content: "\f002"; + font-family: FontAwesome; + position: absolute; + left: 15px; + top: 13px; + color:#454545; + } + } .menu_item { margin: 0px; @@ -126,6 +150,10 @@ content: "\2713"; } } + + &.hidden { + display: none; + } } .menu_item:hover {