Select2 dropdown position, how to force below?

Forums › Forums › Search & Filter Pro › Select2 dropdown position, how to force below?

Viewing 4 posts – 1 through 4 (of 4 total)
  • Anonymous
    #270286

    How can I force the Select2 dropdown to always show below? Right now it shows above if there is not enough space at the bottom of the viewport. There is a solution on Github but is there a way to do this without hacking the core files? I assume when S&F is updated, it will overwrite them anyway.

    https://github.com/select2/select2/issues/3121

    Trevor
    #270311

    We use the standard Select2 library, so you may be able to use some custom JavaScript to change this behaviour, but that is not something I have done before, and you would need to code this yourself. If you alter any core files, you need to keep copies, as any update will overwrite them.

    Anonymous
    #270335

    OK I figured it out.

       (function($) {
    
            var Defaults = $.fn.select2.amd.require('select2/defaults');
    
            $.extend(Defaults.defaults, {
                dropdownPosition: 'auto'
            });
    
            var AttachBody = $.fn.select2.amd.require('select2/dropdown/attachBody');
    
            var _positionDropdown = AttachBody.prototype._positionDropdown;
    
            AttachBody.prototype._positionDropdown = function() {
    
                var $window = $(window);
    
                var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above');
                var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below');
    
                var newDirection = null;
    
                var offset = this.$container.offset();
    
                offset.bottom = offset.top + this.$container.outerHeight(false);
    
                var container = {
                    height: this.$container.outerHeight(false)
                };
    
                container.top = offset.top;
                container.bottom = offset.top + container.height;
    
                var dropdown = {
                    height: this.$dropdown.outerHeight(false)
                };
    
                var viewport = {
                    top: $window.scrollTop(),
                    bottom: $window.scrollTop() + $window.height()
                };
    
                var enoughRoomAbove = viewport.top < (offset.top - dropdown.height);
                var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height);
    
                var css = {
                    left: offset.left,
                    top: container.bottom
                };
    
                // Determine what the parent element is to use for calciulating the offset
                var $offsetParent = this.$dropdownParent;
    
                // For statically positoned elements, we need to get the element
                // that is determining the offset
                if ($offsetParent.css('position') === 'static') {
                    $offsetParent = $offsetParent.offsetParent();
                }
    
                var parentOffset = $offsetParent.offset();
    
                css.top -= parentOffset.top
                css.left -= parentOffset.left;
    
                var dropdownPositionOption = this.options.get('dropdownPosition');
    
                if (dropdownPositionOption === 'above' || dropdownPositionOption === 'below') {
                    newDirection = dropdownPositionOption;
                } else {
    
                    if (!isCurrentlyAbove && !isCurrentlyBelow) {
                        newDirection = 'below';
                    }
    
                    if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) {
                        newDirection = 'above';
                    } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) {
                        newDirection = 'below';
                    }
    
                }
    
                if (newDirection == 'above' ||
                    (isCurrentlyAbove && newDirection !== 'below')) {
                    css.top = container.top - parentOffset.top - dropdown.height;
                }
    
                if (newDirection != null) {
                    this.$dropdown
                        .removeClass('select2-dropdown--below select2-dropdown--above')
                        .addClass('select2-dropdown--' + newDirection);
                    this.$container
                        .removeClass('select2-container--below select2-container--above')
                        .addClass('select2-container--' + newDirection);
                }
    
                this.$dropdownContainer.css(css);
    
            };
    
        })(window.jQuery);
    
        jQuery(document).ready(function() {
            jQuery(".sf-input-select").select2({
                dropdownPosition: 'below'
            });
        });
    Trevor
    #270343

    Thanks for sharing. Make sure you test it, especially if you have AutoCount on the form, or Ajax form submission.

Viewing 4 posts – 1 through 4 (of 4 total)

Search & Filter Support
Privacy Overview

This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.

We also use cookies to store items in your cart as well as allowing your to login on the site.

You can adjust all of your cookie settings by navigating the tabs on the left hand side.

By continuing to use this site, you also agree to our Privacy Policy.