mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-02 21:57:17 +00:00
Implements the filter options feature
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user