Skip to content

Commit

Permalink
Merge pull request #3131 from alphagov/open-filters-on-page-load
Browse files Browse the repository at this point in the history
Open filters on page load
  • Loading branch information
jon-kirwan authored Sep 7, 2023
2 parents 1875dfc + 75f8f41 commit 4f3354c
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 95 deletions.
44 changes: 26 additions & 18 deletions app/assets/javascripts/components/option-select.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
this.hasFilter = this.$optionSelect.getAttribute('data-filter-element') || ''

this.checkedCheckboxes = []

this.mq = window.matchMedia('(min-width: 641px)')
this.isClosedOnLoad = this.$optionSelect.getAttribute('data-closed-on-load')
this.isClosedOnLoadMobile = this.$optionSelect.getAttribute('data-closed-on-load-mobile')
}

OptionSelect.prototype.init = function () {
Expand Down Expand Up @@ -57,25 +61,13 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
var button = this.$optionSelect.querySelector('.js-container-button')
button.addEventListener('click', this.toggleOptionSelect.bind(this))

var closedOnLoad = this.$optionSelect.getAttribute('data-closed-on-load')
var closedOnLoadMobile = this.$optionSelect.getAttribute('data-closed-on-load-mobile')

// By default the .filter-content container is hidden on mobile
// By checking if .filter-content is hidden, we are in mobile view given the current implementation
var isFacetsContentHidden = this.isFacetsContainerHidden()

// Check if the option select should be closed for mobile screen sizes
var closedForMobile = closedOnLoadMobile === 'true' && isFacetsContentHidden

// Always set the contain height to 200px for mobile screen sizes
if (closedForMobile) {
this.setContainerHeight(200)
}

if (closedOnLoad === 'true' || closedForMobile) {
this.close()
// Toggle option visibility depending on screen size (min-width: 641px) and
// presence of any 'closed' properties (`data-closed-on-load`, `data-closed-on-load-mobile`).
// See https://github.com/alphagov/govuk-frontend/blob/main/packages/govuk-frontend/src/govuk/settings/_media-queries.scss#L10-L14
if (this.mq.matches) {
this.toggleVisibility(true)
} else {
this.setupHeight()
this.toggleVisibility(false)
}

var checkedString = this.checkedString()
Expand All @@ -84,6 +76,22 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
}
}

OptionSelect.prototype.toggleVisibility = function (isTabletOrLarger) {
if (isTabletOrLarger) {
if (this.isClosedOnLoad === 'true') {
this.close()
} else {
this.setupHeight()
}
} else {
if (this.isClosedOnLoadMobile === 'true' || this.isClosedOnLoad === 'true') {
this.close()
} else {
this.setContainerHeight(201)
}
}
}

OptionSelect.prototype.typeFilterText = function (event) {
event.stopPropagation()
var ENTER_KEY = 13
Expand Down
4 changes: 4 additions & 0 deletions app/assets/javascripts/modules/mobile-filters-modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
this.triggerElement.addEventListener('click', this.module.toggle)
this.triggerElement.setAttribute('aria-controls', this.module.id)
this.triggerElement.setAttribute('aria-expanded', 'false')
// Open filter on page load if data attribute "open_on_load" is present
if (this.triggerElement.getAttribute('data-open-on-load') === 'true') {
this.triggerElement.click()
}
}

if (this.clearFiltersTrigger) {
Expand Down
4 changes: 4 additions & 0 deletions app/models/content_item.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ def filter
content_item_hash.dig("details", "filter") || {}
end

def open_filter_on_load
content_item_hash.dig("details", "open_filter_on_load") || ""
end

def reject
content_item_hash.dig("details", "reject") || {}
end
Expand Down
1 change: 1 addition & 0 deletions app/views/finders/_filter_button.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
data-track-label=""
data-module="ga4-event-tracker"
data-ga4-expandable=""
data-open-on-load="<%= @content_item.open_filter_on_load %>"
>
Filter <span class="govuk-visually-hidden"> results</span>
<span class="js-selected-filter-count"><%= sanitize facet_tags.display_total_selected_filters %></span>
Expand Down
174 changes: 97 additions & 77 deletions spec/javascripts/modules/mobile-filters-modal.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
describe('Mobile filters modal', function () {
describe('Mobile filters', function () {
'use strict'

var container
Expand Down Expand Up @@ -44,107 +44,127 @@ describe('Mobile filters modal', function () {
container.addEventListener('submit', function (e) {
e.preventDefault()
})

var element = $('[data-module="mobile-filters-modal"]')[0]
new GOVUK.Modules.MobileFiltersModal(element).init()
})

afterEach(function () {
document.body.removeChild(container)
})

describe('open button', function () {
describe('Mobile filters modal', function () {
beforeEach(function () {
document.querySelector('.js-toggle-mobile-filters').click()
})

afterEach(function () {
document.querySelector('.js-toggle-mobile-filters').click()
})

it('should show the modal', function () {
var modal = document.querySelector('.facets')
expect($(modal).hasClass('facets--visible')).toBe(true)
var element = $('[data-module="mobile-filters-modal"]')[0]
new GOVUK.Modules.MobileFiltersModal(element).init()
})

it('should hide the modal', function () {
var modal = document.querySelector('.facets')
document.querySelector('.js-toggle-mobile-filters').click()
expect($(modal).hasClass('facets--visible')).toBe(false)
describe('open button', function () {
beforeEach(function () {
document.querySelector('.js-toggle-mobile-filters').click()
})

afterEach(function () {
document.querySelector('.js-toggle-mobile-filters').click()
})

it('should show the modal', function () {
var modal = document.querySelector('.facets')
expect($(modal).hasClass('facets--visible')).toBe(true)
})

it('should hide the modal', function () {
var modal = document.querySelector('.facets')
document.querySelector('.js-toggle-mobile-filters').click()
expect($(modal).hasClass('facets--visible')).toBe(false)
})
})
})

describe('open', function () {
beforeEach(function () {
var modal = document.querySelector('.facets')
modal.open()
describe('open', function () {
beforeEach(function () {
var modal = document.querySelector('.facets')
modal.open()
})

afterEach(function () {
var modal = document.querySelector('.facets')
modal.close()
})

it('should show the modal', function () {
var modal = document.querySelector('.facets')
expect($(modal).hasClass('facets--visible')).toBe(true)
})
})

afterEach(function () {
var modal = document.querySelector('.facets')
modal.close()
describe('close', function () {
it('should hide the modal', function () {
var modal = document.querySelector('.facets')
modal.open()
modal.close()
expect($(modal).hasClass('facets--visible')).toBe(false)
})
})

it('should show the modal', function () {
var modal = document.querySelector('.facets')
expect($(modal).hasClass('facets--visible')).toBe(true)
describe('clear filters', function () {
it('should reset checkboxes, clear text input and <select> values', function () {
var modal = document.querySelector('.facets')
modal.clearFilters()
expect($(modal).find('input:checked').length).toBe(0)
// number of text inputs with value should now be 0
expect($(modal).find('input[type="text"]')
.filter(function () { return $(this).val() }).length).toBe(0)
expect($(modal).find('select').val()).toBe('')
})
})
})

describe('close', function () {
it('should hide the modal', function () {
var modal = document.querySelector('.facets')
modal.open()
modal.close()
expect($(modal).hasClass('facets--visible')).toBe(false)
describe('accessibility', function () {
it('should add aria-expanded="false" on load to the Filter button', function () {
var button = document.querySelector('.js-toggle-mobile-filters')
expect(button.getAttribute('aria-expanded')).toEqual('false')
})

it('should set aria-expanded to true when clicking the Filter button', function () {
var button = document.querySelector('.js-toggle-mobile-filters')
button.click()
expect(button.getAttribute('aria-expanded')).toEqual('true')
})

it('should add aria-controls on load to the Filter button', function () {
var button = document.querySelector('.js-toggle-mobile-filters')
expect(button.getAttribute('aria-controls')).toEqual('facet-wrapper')
expect(document.querySelector('#facet-wrapper')).not.toEqual(null)
})
})
})

describe('clear filters', function () {
it('should reset checkboxes, clear text input and <select> values', function () {
var modal = document.querySelector('.facets')
modal.clearFilters()
expect($(modal).find('input:checked').length).toBe(0)
// number of text inputs with value should now be 0
expect($(modal).find('input[type="text"]')
.filter(function () { return $(this).val() }).length).toBe(0)
expect($(modal).find('select').val()).toBe('')
describe('ga4 tracking', function () {
it('adds the ga4 event tracker to the button', function () {
var button = document.querySelector('.js-toggle-mobile-filters')
var expected = {
event_name: 'select_content',
type: 'finder',
text: 'Filter',
section: 'Filter',
index: {
index_section: 0,
index_section_count: 5
}
}
expect(button.getAttribute('data-ga4-event')).toEqual(JSON.stringify(expected))
})
})
})

describe('accessibility', function () {
it('should add aria-expanded="false" on load to the Filter button', function () {
var button = document.querySelector('.js-toggle-mobile-filters')
expect(button.getAttribute('aria-expanded')).toEqual('false')
})

it('should set aria-expanded to true when clicking the Filter button', function () {
var button = document.querySelector('.js-toggle-mobile-filters')
button.click()
expect(button.getAttribute('aria-expanded')).toEqual('true')
})
describe('Mobile filters modal (open on load)', function () {
beforeEach(function () {
container.querySelector('button').dataset.openOnLoad = true

it('should add aria-controls on load to the Filter button', function () {
var button = document.querySelector('.js-toggle-mobile-filters')
expect(button.getAttribute('aria-controls')).toEqual('facet-wrapper')
expect(document.querySelector('#facet-wrapper')).not.toEqual(null)
var element = $('[data-module="mobile-filters-modal"]')[0]
new GOVUK.Modules.MobileFiltersModal(element).init()
})
})

describe('ga4 tracking', function () {
it('adds the ga4 event tracker to the button', function () {
var button = document.querySelector('.js-toggle-mobile-filters')
var expected = {
event_name: 'select_content',
type: 'finder',
text: 'Filter',
section: 'Filter',
index: {
index_section: 0,
index_section_count: 5
}
}
expect(button.getAttribute('data-ga4-event')).toEqual(JSON.stringify(expected))
describe('open on load', function () {
it('should show the modal', function () {
var modal = document.querySelector('.facets')
expect($(modal).hasClass('facets--visible')).toBe(true)
})
})
})
})

0 comments on commit 4f3354c

Please sign in to comment.