Auto-scroll window as needed to ensure drop-down choices are visible

This commit is contained in:
Lance Edgar 2017-11-22 11:21:59 -06:00
parent 40d2251844
commit 43ce0fb44f
3 changed files with 60 additions and 2 deletions

View file

@ -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. // Intercept filters form submittal, and submit via AJAX instead.
this.filters_form.on('submit', function() { this.filters_form.on('submit', function() {
var settings = {filter: true, partial: true}; 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. // Enhance any date values with datepicker widget.
this.inputs.find('.value input[type="date"]').datepicker({ this.inputs.find('.value input[type="date"]').datepicker({
dateFormat: 'yy-mm-dd', dateFormat: 'yy-mm-dd',
@ -267,7 +275,12 @@
// Enhance any choice/dropdown values with selectmenu. // Enhance any choice/dropdown values with selectmenu.
this.inputs.find('.value select').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. // Listen for button click, to keep checkbox in sync.

View file

@ -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 * reference to existing timeout warning dialog, if any
*/ */
@ -194,6 +225,9 @@ $(function() {
* enhance dropdowns * enhance dropdowns
*/ */
$('select[auto-enhance="true"]').selectmenu(); $('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. */ /* Also automatically disable any buttons marked for that. */
$('a.button[disabled=disabled]').button('option', 'disabled', true); $('a.button[disabled=disabled]').button('option', 'disabled', true);

View file

@ -17,7 +17,7 @@
class string: form-control ${css_class or ''}; class string: form-control ${css_class or ''};
multiple multiple; multiple multiple;
size size; size size;
style style;" auto-enhance="true"> style style;">
<tal:loop tal:repeat="item values"> <tal:loop tal:repeat="item values">
<optgroup tal:condition="isinstance(item, optgroup_class)" <optgroup tal:condition="isinstance(item, optgroup_class)"
tal:attributes="label item.label"> tal:attributes="label item.label">
@ -38,4 +38,15 @@
</select> </select>
<input type="hidden" name="__end__" value="${name}:sequence" <input type="hidden" name="__end__" value="${name}:sequence"
tal:condition="multiple" /> tal:condition="multiple" />
<script type="text/javascript">
deform.addCallback(
'${oid}',
function(oid) {
$('#' + oid).selectmenu();
$('#' + oid).on('selectmenuopen', function(event, ui) {
show_all_options($(this));
});
}
);
</script>
</div> </div>