Skip to content

Commit

Permalink
Fix [Search pills] Counter bug and "All" buttons removed. (#478)
Browse files Browse the repository at this point in the history
* Fix (Search pills): All button. Removed all button feature because of users feedback.

* Fix (Search pills): Pills counter bug. Refactored how pills were counted, added target to make the feature more roubust.

* Removed select-all-checkbox  yarn package.
  • Loading branch information
JosueMagnus12 authored Oct 13, 2023
1 parent 9dc7d8c commit a9d999f
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 108 deletions.
1 change: 1 addition & 0 deletions app/components/search_pills/button/component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ def initialize(name:, value:, checked:, copy:, options: {})
class: "hidden pill",
id: SecureRandom.alphanumeric,
data: {
search_target: "pill",
action: "click->search#toggleRadioButton change->search#updateFiltersState change->search#submitForm",
}
}
Expand Down
104 changes: 50 additions & 54 deletions app/components/search_pills/component.html.slim
Original file line number Diff line number Diff line change
@@ -1,56 +1,52 @@
div class="w-full bg-gray-9"
div data-search-target="pills"
div data-controller="tabs" data-tabs-active-tab=("border-b-4 border-blue-medium")
div class="flex"
/ Clear-Counter button
span class="flex justify-center items-center w-14 pl-5 py-3 pr-2 text-xs bg-blue-pale"
span class="inline-flex hidden items-center px-1 py-0.5 border border-blue-medium rounded-full bg-white" data-search-target="pillsCounterWrapper"
span data-search-target="pillsCounter" class="mr-0.5"
button type="button" data-action="search#clearCheckedPills"
= inline_svg_tag "x-icon.svg", class: 'h-2 w-2 fill-current stroke-current stroke-1 text-blue-medium ml-1 relative'
= inline_svg_tag "solid_filters.svg", class: 'h-4 w-4 fill-current text-gray-2 -ml-0.5 relative', data: { 'search-target': "filtersIcon" }
/ Tabs
ul class="flex flex-1 gap-x-6 pl-5 pr-6 text-sm list-none overflow-x-auto overflow-y-hidden bg-blue-pale text-gray-2"
- @tabs_labels.each do |tab_label|
li data-action="click->tabs#change" data-tabs-target="tab"
a class="inline-block py-3 whitespace-nowrap" href="#" = tab_label
li data-action="click->modal#open"
button class="inline-block py-3 whitespace-nowrap" type="button" id="advanced-filters-button"
| Advanced Filters
span class="relative hidden w-2 h-2 rounded-full bg-salmon ml-1 mb-2" id="appliedIcon"
div data-controller="tabs" data-tabs-active-tab=("border-b-4 border-blue-medium")
div class="flex"
/ Clear-Counter button
span class="flex justify-center items-center w-14 pl-5 py-3 pr-2 text-xs bg-blue-pale"
span class="inline-flex hidden items-center px-1 py-0.5 border border-blue-medium rounded-full bg-white" data-search-target="pillsCounterWrapper"
span data-search-target="pillsCounter" class="mr-0.5"
button type="button" data-action="search#clearCheckedPills"
= inline_svg_tag "x-icon.svg", class: 'h-2 w-2 fill-current stroke-current stroke-1 text-blue-medium ml-1 relative'
= inline_svg_tag "solid_filters.svg", class: 'h-4 w-4 fill-current text-gray-2 -ml-0.5 relative', data: { 'search-target': "filtersIcon" }
/ Tabs
ul class="flex flex-1 gap-x-6 pl-5 pr-6 text-sm list-none overflow-x-auto overflow-y-hidden bg-blue-pale text-gray-2"
- @tabs_labels.each do |tab_label|
li data-action="click->tabs#change" data-tabs-target="tab"
a class="inline-block py-3 whitespace-nowrap" href="#" = tab_label
li data-action="click->modal#open"
button class="inline-block py-3 whitespace-nowrap" type="button" id="advanced-filters-button"
| Advanced Filters
span class="relative hidden w-2 h-2 rounded-full bg-salmon ml-1 mb-2" id="appliedIcon"

/ Panels
div class="bg-white"
/ Causes
div class="flex flex-wrap gap-x-2 gap-y-3 hidden max-h-28 py-4 px-6 border-l border-b border-r overflow-y-auto" data-controller="checkbox-select-all" data-tabs-target="panel"
= render SearchPills::Pill::Component.new(name: "causes_all", value: 'All', checked: all_causes_checked?, options: { data: { checkbox_select_all_target: "checkboxAll", action: "change->checkbox-select-all#toggle" }})
- @causes.each do |cause|
= render SearchPills::Pill::Component.new(name: "search[causes][]", value: cause.name, checked: @params.dig(:search, :causes)&.include?(cause.name), options: { multiple: true, data: { action: "change->checkbox-select-all#refresh", checkbox_select_all_target: "checkbox"}})
= render SearchPills::MoreFiltersButton::Component.new
/ Location
div class="flex flex-col hidden border-b md:flex-row md:items-center" data-tabs-target="panel"
div class="py-4 pl-6 text-gray-2 text-sm"
span class="inline-flex items-center"
= inline_svg_tag "location-dot.svg", class: "h-3 w-3 fill-current text-blue-medium mr-1"
| Nashville
div class="flex w-full md:w-auto md:py-3.5 md:pl-7"
- @radii_in_miles.each do |radius|
= render SearchPills::Button::Component.new(name: "search[distance]", value: miles_to_km(radius), checked: @params.dig(:search, :distance) == miles_to_km(radius).to_s, copy: radius == "Any" ? radius : "#{radius} mi")
/ Services
div class="flex flex-wrap gap-x-2 gap-y-3 hidden max-h-28 py-4 px-6 border-l border-b border-r overflow-y-auto" data-controller="checkbox-select-all" data-tabs-target="panel"
= render SearchPills::Pill::Component.new(name: "services_all", value: 'All', checked: all_services_checked?, options: { data: { checkbox_select_all_target: "checkboxAll", action: "change->checkbox-select-all#toggle" }})
- @services.each do |service|
= render SearchPills::Pill::Component.new(name: "search[services][#{service.cause.name}][]", value: service.name, checked: @params.dig('search', 'services', service.cause.name)&.include?(service.name), options: { multiple: true, data: { action: 'change->checkbox-select-all#refresh', checkbox_select_all_target: 'checkbox'}})
= render SearchPills::MoreFiltersButton::Component.new
/ Populations Served
div class="flex flex-wrap gap-x-2 gap-y-3 hidden max-h-28 py-4 px-6 border-l border-b border-r overflow-y-auto" data-controller="checkbox-select-all" data-tabs-target="panel"
= render SearchPills::Pill::Component.new(name: "groups_all", value: 'All', checked: all_beneficiary_subcategories_checked?, options: { data: { checkbox_select_all_target: "checkboxAll", action: "change->checkbox-select-all#toggle" }})
- @beneficiary_subcategories.each do |subcategory|
= render SearchPills::Pill::Component.new(name: "search[beneficiary_groups][#{subcategory.beneficiary_group.name}][]", value: subcategory.name, checked: @params.dig('search', 'beneficiary_groups', subcategory.beneficiary_group.name)&.include?(subcategory.name), options: { multiple: true, data: { action: 'change->checkbox-select-all#refresh', checkbox_select_all_target: 'checkbox'}})
= render SearchPills::MoreFiltersButton::Component.new
/ Hours
div class="flex hidden gap-x-2 w-full py-4 px-6 border-l border-b border-r" data-tabs-target="panel"
= render SearchPills::Pill::Component.new(name: "search[open_now]", value: true, checked: @params.dig('search', 'open_now') == 'true') do
| Open Now
= render SearchPills::Pill::Component.new(name: "search[open_weekends]", value: true, checked: @params.dig('search', 'open_weekends') == 'true') do
| Open Weekends
/ Panels
div class="bg-white"
/ Causes
div class="flex flex-wrap gap-x-2 gap-y-3 hidden max-h-28 py-4 px-6 border-l border-b border-r overflow-y-auto" data-tabs-target="panel"
- @causes.each do |cause|
= render SearchPills::Pill::Component.new(name: "search[causes][]", value: cause.name, checked: @params.dig(:search, :causes)&.include?(cause.name), options: { multiple: true })
= render SearchPills::MoreFiltersButton::Component.new
/ Location
div class="flex flex-col hidden border-b md:flex-row md:items-center" data-tabs-target="panel"
div class="py-4 pl-6 text-gray-2 text-sm"
span class="inline-flex items-center"
= inline_svg_tag "location-dot.svg", class: "h-3 w-3 fill-current text-blue-medium mr-1"
| Nashville
div class="flex w-full md:w-auto md:py-3.5 md:pl-7"
- @radii_in_miles.each do |radius|
= render SearchPills::Button::Component.new(name: "search[distance]", value: miles_to_km(radius), checked: @params.dig(:search, :distance) == miles_to_km(radius).to_s, copy: radius == "Any" ? radius : "#{radius} mi")
/ Services
div class="flex flex-wrap gap-x-2 gap-y-3 hidden max-h-28 py-4 px-6 border-l border-b border-r overflow-y-auto" data-tabs-target="panel"
- @services.each do |service|
= render SearchPills::Pill::Component.new(name: "search[services][#{service.cause.name}][]", value: service.name, checked: @params.dig('search', 'services', service.cause.name)&.include?(service.name), options: { multiple: true })
= render SearchPills::MoreFiltersButton::Component.new
/ Populations Served
div class="flex flex-wrap gap-x-2 gap-y-3 hidden max-h-28 py-4 px-6 border-l border-b border-r overflow-y-auto" data-tabs-target="panel"
- @beneficiary_subcategories.each do |subcategory|
= render SearchPills::Pill::Component.new(name: "search[beneficiary_groups][#{subcategory.beneficiary_group.name}][]", value: subcategory.name, checked: @params.dig('search', 'beneficiary_groups', subcategory.beneficiary_group.name)&.include?(subcategory.name), options: { multiple: true })
= render SearchPills::MoreFiltersButton::Component.new
/ Hours
div class="flex hidden gap-x-2 w-full py-4 px-6 border-l border-b border-r" data-tabs-target="panel"
= render SearchPills::Pill::Component.new(name: "search[open_now]", value: true, checked: @params.dig('search', 'open_now') == 'true') do
| Open Now
= render SearchPills::Pill::Component.new(name: "search[open_weekends]", value: true, checked: @params.dig('search', 'open_weekends') == 'true') do
| Open Weekends
12 changes: 0 additions & 12 deletions app/components/search_pills/component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,6 @@ def initialize(causes:, services:, beneficiary_subcategories:, params:)
@radii_in_miles = [2, 5, 15, 30, 60, 180, "Any"]
end

def all_causes_checked?
@causes.all? { |cause| @params.dig(:search, :causes)&.include?(cause.name) }
end

def all_services_checked?
@services.all? { |service| @params.dig(:search, :services, service.cause.name)&.include?(service.name) }
end

def all_beneficiary_subcategories_checked?
@beneficiary_subcategories.all? { |subcategory| @params.dig(:search, :beneficiary_groups, subcategory.beneficiary_group.name)&.include?(subcategory.name) }
end

def miles_to_km(miles)
miles == "Any" ? 1_000_000 : (miles * 1.609344).round(3)
end
Expand Down
7 changes: 5 additions & 2 deletions app/components/search_pills/pill/component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ def initialize(name:, value: , checked:, options: { data: {action: ''}})
@options = options.merge(
{
class: 'hidden pill',
id: SecureRandom.alphanumeric
id: SecureRandom.alphanumeric,
data: {
search_target: "pill",
action: "change->places#hidePopup change->search#updateFiltersState change->search#submitForm"
}
}
)
@options[:data][:action] << ' change->places#hidePopup change->search#updateFiltersState change->search#submitForm'
end
end
20 changes: 0 additions & 20 deletions app/javascript/controllers/checkbox_select_all_controller.js

This file was deleted.

23 changes: 11 additions & 12 deletions app/javascript/controllers/search_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default class extends Controller {
"input",
"customInput",
"form",
"pills",
"pill",
"advancedFilters",
"pillsCounter",
"pillsCounterWrapper",
Expand All @@ -34,10 +34,10 @@ export default class extends Controller {
// Unchecks applied advanced filters firing their data-actions,
// which clear displayed badges (see select_multiple_controller.js:15 and select-multiple component).
this.advancedFiltersTarget.querySelectorAll("input:checked").forEach(input => input.click())
this.pillsTarget.querySelectorAll("input:checked").forEach(input => {
input.checked = false
input.removeAttribute('checked')
})
this.pillTargets.forEach(input => {
input.checked = false;
input.removeAttribute('checked');
});

this.updateFiltersState()
this.submitForm()
Expand All @@ -54,17 +54,17 @@ export default class extends Controller {
}

countPills() {
// selects all checked inputs that are not checkboxAll
this.totalChecked = document.querySelectorAll("input:checked").length - 1;
this.pillsCounterTarget.textContent = this.totalChecked
const checkedPills = this.pillTargets.filter(pill => pill.checked);
this.pillsCounterTarget.textContent = checkedPills.length;
return checkedPills.length;
}

submitForm() {
this.formTarget.requestSubmit()
}

displayPillsCounter() {
if (this.totalChecked > 0) {
displayPillsCounter(checkedPillsCount) {
if (checkedPillsCount > 0) {
this.pillsCounterWrapperTarget.classList.remove("hidden")
this.filtersIconTarget.classList.add("hidden")
}
Expand All @@ -75,8 +75,7 @@ export default class extends Controller {
}

updatePillsCounter() {
this.countPills()
this.displayPillsCounter()
this.displayPillsCounter(this.countPills());
}

updateFiltersState() {
Expand Down
2 changes: 1 addition & 1 deletion app/views/searches/_preview.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
= render SearchBar::Component.new(form: f, search: @search)
= turbo_frame_tag "search-pills", src: local_assigns[:src] do
div class="w-full bg-gray-9"
div data-search-target="pills"
div
div data-tabs-active-tab=("border-b-4 border-blue-medium")
div class="flex pb-14 bg-white border-b"
/ Clear-Counter button
Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
"postcss": "^8",
"selectize": "0.12.4",
"stimulus-carousel": "^4.0.0",
"stimulus-checkbox-select-all": "^5.1.0",
"stimulus-use": "^0.50.0-2",
"swiper": "6.8.4",
"tailwindcss": "npm:@tailwindcss/postcss7-compat",
Expand All @@ -30,4 +29,4 @@
"devDependencies": {
"webpack-dev-server": "^3.11.2"
}
}
}
5 changes: 0 additions & 5 deletions yarn.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit a9d999f

Please sign in to comment.