Skip to content

Commit

Permalink
Merge pull request #51 from RRZE-Webteam/FAU-449
Browse files Browse the repository at this point in the history
[FAU-449] Trigger search only when checkbox state changes
  • Loading branch information
zhyian authored Jan 3, 2025
2 parents c3aad86 + c7009a0 commit 06a0f2a
Showing 1 changed file with 84 additions and 35 deletions.
119 changes: 84 additions & 35 deletions resources/ts/filters/filter-dropdown.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,100 @@
import submitForm from '../form/form-handler';
import isReducedMotion from '../common/reduced-motion-detection';

const DROPDOWN_SELECTOR = '.fau-dropdown';
const DROPDOWN_TOGGLE_SELECTOR = '.fau-dropdown__toggle';
const DROPDOWN_CONTENT_SELECTOR = '.fau-dropdown__content';
const CLICKAWAY_WINDOW_WIDTH_THRESHOLD = 768; // close on click away only works on screen sizes above this value

const closeDropDown = ( dropdown: HTMLElement ) => {
dropdown.setAttribute( 'aria-expanded', 'false' );
submitForm();
};
class Dropdown {
private dropdown: HTMLElement;
private toggle: HTMLElement;
private content: HTMLElement;
private checkboxes: HTMLInputElement[];
private initialState: boolean[] = [];

const toggleDropdown = ( dropdown: HTMLElement ) => {
const isAriaExpanded = dropdown.getAttribute( 'aria-expanded' ) === 'true';
constructor( dropdown: HTMLElement ) {
this.dropdown = dropdown;
this.toggle = dropdown.querySelector( DROPDOWN_TOGGLE_SELECTOR )!;
this.content = dropdown.querySelector( DROPDOWN_CONTENT_SELECTOR )!;
this.checkboxes = Array.from(
this.content.querySelectorAll( 'input[type="checkbox"]' )
);

dropdown.setAttribute( 'aria-expanded', isAriaExpanded ? 'false' : 'true' );
this.init();
}

if ( isAriaExpanded ) {
submitForm();
private recordInitialState() {
this.initialState = this.checkboxes.map(
( checkbox ) => checkbox.checked
);
}
};

const registerClickListeners = () => {
private hasStateChanged(): boolean {
const currentState = this.checkboxes.map(
( checkbox ) => checkbox.checked
);

return this.initialState.some(
( value, index ) => value !== currentState[ index ]
);
}

private close() {
this.dropdown.setAttribute( 'aria-expanded', 'false' );

if ( this.hasStateChanged() && isReducedMotion() ) {
submitForm();
}
}

private toggleDropdown() {
const isAriaExpanded =
this.dropdown.getAttribute( 'aria-expanded' ) === 'true';

if ( ! isAriaExpanded ) {
this.recordInitialState();
}

this.dropdown.setAttribute(
'aria-expanded',
isAriaExpanded ? 'false' : 'true'
);

if ( isAriaExpanded && isReducedMotion() && this.hasStateChanged() ) {
submitForm();
}
}

private handleBodyClick( event: MouseEvent ) {
const target = event.target as Node;

if ( this.toggle.contains( target ) ) {
this.toggleDropdown();
return;
}

if (
this.dropdown.getAttribute( 'aria-expanded' ) === 'true' &&
! this.dropdown.contains( target ) &&
window.innerWidth > CLICKAWAY_WINDOW_WIDTH_THRESHOLD
) {
this.close();
}
}

private init() {
document.body.addEventListener(
'click',
this.handleBodyClick.bind( this )
);
}
}

const registerDropdowns = () => {
document
.querySelectorAll< HTMLElement >( DROPDOWN_SELECTOR )
.forEach( ( dropdown ) => {
const toggle = dropdown.querySelector( DROPDOWN_TOGGLE_SELECTOR );
const content = dropdown.querySelector( DROPDOWN_CONTENT_SELECTOR );

if ( ! toggle || ! content ) {
return;
}

document.body.addEventListener( 'click', ( event ) => {
if ( toggle.contains( event.target as Node ) ) {
toggleDropdown( dropdown );
return;
}

if (
dropdown.getAttribute( 'aria-expanded' ) === 'true' &&
! dropdown.contains( event.target as Node ) &&
window.innerWidth > CLICKAWAY_WINDOW_WIDTH_THRESHOLD
) {
closeDropDown( dropdown );
}
} );
} );
.forEach( ( dropdown ) => new Dropdown( dropdown ) );
};

registerClickListeners();
registerDropdowns();

0 comments on commit 06a0f2a

Please sign in to comment.