From 43ce0fb44fac8a2bc9ac87686a73d806cf89e731 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Wed, 22 Nov 2017 11:21:59 -0600 Subject: [PATCH] Auto-scroll window as needed to ensure drop-down choices are visible --- tailbone/static/js/jquery.ui.tailbone.js | 15 ++++++++++- tailbone/static/js/tailbone.js | 34 ++++++++++++++++++++++++ tailbone/templates/deform/select.pt | 13 ++++++++- 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/tailbone/static/js/jquery.ui.tailbone.js b/tailbone/static/js/jquery.ui.tailbone.js index a5a4dadc..08908e74 100644 --- a/tailbone/static/js/jquery.ui.tailbone.js +++ b/tailbone/static/js/jquery.ui.tailbone.js @@ -58,6 +58,10 @@ } }); + this.add_filter.on('selectmenuopen', function(event, ui) { + show_all_options($(this)); + }); + // Intercept filters form submittal, and submit via AJAX instead. this.filters_form.on('submit', function() { var settings = {filter: true, partial: true}; @@ -258,6 +262,10 @@ } }); + this.verb_select.on('selectmenuopen', function(event, ui) { + show_all_options($(this)); + }); + // Enhance any date values with datepicker widget. this.inputs.find('.value input[type="date"]').datepicker({ dateFormat: 'yy-mm-dd', @@ -267,7 +275,12 @@ // Enhance any choice/dropdown values with selectmenu. this.inputs.find('.value select').selectmenu({ - width: '15em' + // TODO: don't remember why this was here, but seems unwanted + // width: '15em' + }); + + this.inputs.find('.value select').on('selectmenuopen', function(event, ui) { + show_all_options($(this)); }); // Listen for button click, to keep checkbox in sync. diff --git a/tailbone/static/js/tailbone.js b/tailbone/static/js/tailbone.js index 5b6e6d92..67f9a409 100644 --- a/tailbone/static/js/tailbone.js +++ b/tailbone/static/js/tailbone.js @@ -89,6 +89,37 @@ function dialog_button(event) { } +/** + * Scroll screen as needed to ensure all options are visible, for the given + * select menu widget. + */ +function show_all_options(select) { + if (! select.is(':visible')) { + /* + * Note that the following code was largely stolen from + * http://brianseekford.com/2013/06/03/how-to-scroll-a-container-or-element-into-view-using-jquery-javascript-in-your-html/ + */ + + var docViewTop = $(window).scrollTop(); + var docViewBottom = docViewTop + $(window).height(); + + var widget = select.selectmenu('menuWidget'); + var elemTop = widget.offset().top; + var elemBottom = elemTop + widget.height(); + + var isScrolled = ((elemBottom <= docViewBottom) && (elemTop >= docViewTop)); + + if (!isScrolled) { + if (widget.height() > $(window).height()) { //then just bring to top of the container + $(window).scrollTop(elemTop) + } else { //try and and bring bottom of container to bottom of screen + $(window).scrollTop(elemTop - ($(window).height() - widget.height())); + } + } + } +} + + /* * reference to existing timeout warning dialog, if any */ @@ -194,6 +225,9 @@ $(function() { * enhance dropdowns */ $('select[auto-enhance="true"]').selectmenu(); + $('select[auto-enhance="true"]').on('selectmenuopen', function(event, ui) { + show_all_options($(this)); + }); /* Also automatically disable any buttons marked for that. */ $('a.button[disabled=disabled]').button('option', 'disabled', true); diff --git a/tailbone/templates/deform/select.pt b/tailbone/templates/deform/select.pt index 5bae0ecb..1fe8dade 100644 --- a/tailbone/templates/deform/select.pt +++ b/tailbone/templates/deform/select.pt @@ -17,7 +17,7 @@ class string: form-control ${css_class or ''}; multiple multiple; size size; - style style;" auto-enhance="true"> + style style;"> @@ -38,4 +38,15 @@ +