From 453cc373417fb6fb4c21f8cb6b24964ccfc5ab4a Mon Sep 17 00:00:00 2001 From: Abijeet Date: Fri, 16 Dec 2022 20:13:53 +0530 Subject: [PATCH] Fix general and usability issues, add some more features * Scoll to currently highlighted item if its not visible. * Fix navigation when list is filtered * Add support for selecting highlighted item by pressing enter --- src/jquery.uls.languagefilter.js | 5 ++- src/jquery.uls.lcd.js | 58 ++++++++++++++++++++++---------- 2 files changed, 44 insertions(+), 19 deletions(-) diff --git a/src/jquery.uls.languagefilter.js b/src/jquery.uls.languagefilter.js index c9d8005..600287b 100644 --- a/src/jquery.uls.languagefilter.js +++ b/src/jquery.uls.languagefilter.js @@ -106,7 +106,10 @@ query = ( this.$element.val() || '' ).trim().toLowerCase(); - if ( this.selectedLanguage ) { + var highlightedLanguage = this.options.lcd.getHighlightedLanguageCode(); + if ( highlightedLanguage ) { + this.options.onSelect( highlightedLanguage, e ); + } else if ( this.selectedLanguage ) { // this.selectLanguage will be populated from a matching search this.options.onSelect( this.selectedLanguage, e ); } else if ( this.options.languages[ query ] ) { diff --git a/src/jquery.uls.lcd.js b/src/jquery.uls.lcd.js index b6568b6..251d81f 100644 --- a/src/jquery.uls.lcd.js +++ b/src/jquery.uls.lcd.js @@ -70,21 +70,27 @@ this.listen(); } + // Adapted from https://stackoverflow.com/a/41754707/903324 + function isLanguageFullyVisible( $el, $holder ) { + var elementRect = $el.get( 0 ).getBoundingClientRect(); + var holderRect = $holder.get( 0 ).getBoundingClientRect(); + + return elementRect.top <= holderRect.top ? + holderRect.top <= elementRect.top : + holderRect.bottom <= elementRect.height; + } + LanguageCategoryDisplay.prototype = { constructor: LanguageCategoryDisplay, /** - * Returns a jQuery object containing a collection of all the + * Returns a jQuery object containing a collection of all the visible * language option
  • elements * * @return {jQuery} */ getLanguageOptionListItems: function () { - if ( !this.$languageOptionListItems ) { - this.$languageOptionListItems = this.$element.find( 'li[data-code]' ); - } - - return this.$languageOptionListItems; + return this.$element.find( '.uls-lcd-region-section:not(.hide)' ).find( 'li[data-code]' ); }, /** @@ -138,8 +144,24 @@ * language option
  • element (where n = navigation index) */ highlightLanguageOption: function () { - this.getLanguageOptionListItems().removeClass( 'language-option--highlighted' ); - this.getLanguageOptionListItems().eq( this.navigationIndex ).addClass( 'language-option--highlighted' ); + var $listItems = this.getLanguageOptionListItems(); + $listItems.removeClass( 'language-option--highlighted' ); + + var $selectedItem = $listItems.eq( this.navigationIndex ); + $selectedItem.addClass( 'language-option--highlighted' ); + + if ( !isLanguageFullyVisible( $selectedItem, this.$element ) ) { + $selectedItem.get( 0 ).scrollIntoView( false ); + } + }, + + getHighlightedLanguageCode: function () { + if ( this.navigationIndex ) { + var $selectedItem = this.getLanguageOptionListItems().eq( this.navigationIndex ); + return $selectedItem.data( 'code' ); + } + + return null; }, /** @@ -503,16 +525,16 @@ listen: function () { var lcd = this; - this.$element.on( 'mouseenter', '.row li', function () { - lcd.navigationIndex = $( this ).index(); - lcd.highlightLanguageOption(); - } ); - - this.$element.on( 'mouseleave', '.row li', function () { - if ( lcd.navigationIndex === $( this ).index() ) { - lcd.navigationIndex = null; - lcd.getLanguageOptionListItems().removeClass( 'language-option--highlighted' ); - } + this.$element.on( 'mouseenter', 'li[data-code]', function () { + var $listItems = lcd.getLanguageOptionListItems(); + // Remove the previous option, and then highlight the current one. + $listItems.removeClass( 'language-option--highlighted' ); + var $self = $( this ); + $self.addClass( 'language-option--highlighted' ); + lcd.navigationIndex = $listItems.index( $self ); + } ).on( 'mouseleave', 'li[data-code]', function () { + $( this ).removeClass( 'language-option--highlighted' ); + lcd.navigationIndex = null; } ); if ( this.options.clickhandler ) {