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 ) {