jQuery UI SelectMenu Dropdown - opens UP instead of DOWN

前端 未结 2 1349
时光说笑
时光说笑 2021-01-06 11:43

I\'m using jQuery UI Select Menu and occasionally have some issues.

This is located at the top left of my users\' pages. Using the \"dropdown/address\" type, someti

2条回答
  •  北海茫月
    2021-01-06 12:42

    The plugin uses the Position utility of the jQuery UI library. If you look at the default options in the source of the plugin, there is a positionOptions property that is used in the function _refreshPosition():

    options: {
        transferClasses: true,
        typeAhead: 1000,
        style: 'dropdown',
        positionOptions: {
            my: "left top",
            at: "left bottom",
            offset: null
        },
        width: null,
        menuWidth: null,
        handleWidth: 26,
        maxHeight: null,
        icons: null,
        format: null,
        bgImage: function() {},
        wrapperElement: "
    " } _refreshPosition: function() { var o = this.options; // if its a pop-up we need to calculate the position of the selected li if ( o.style == "popup" && !o.positionOptions.offset ) { var selected = this._selectedOptionLi(); var _offset = "0 " + ( this.list.offset().top - selected.offset().top - ( this.newelement.outerHeight() + selected.outerHeight() ) / 2); } // update zIndex if jQuery UI is able to process this.listWrap .zIndex( this.element.zIndex() + 1 ) .position({ // set options for position plugin of: o.positionOptions.of || this.newelement, my: o.positionOptions.my, at: o.positionOptions.at, offset: o.positionOptions.offset || _offset, collision: o.positionOptions.collision || 'flip' }); }

    You can see it uses a default value 'flip' if none is provided for the collision option of the position utility which is. According to jQuery UI documentation:

    flip: to the opposite side and the collision detection is run again to see if it will fit. If it won't fit in either position, the center option should be used as a fall back.
    fit: so the element keeps in the desired direction, but is re-positioned so it fits.
    none: not do collision detection.

    So i guess you could pass an option when initializing the plugin to define none for the collision option:

    $('select').selectmenu({
        positionOptions: {
            collision: 'none'
        }
    });
    

    Have not tested yet, this is just by looking at the code.


    Edit following comment

    I've noticed that the version of the javascript available on github and the one used on the plugin website are not the same. I don't know which one you are using but the one used on the website does not have a positionOptions option actually, so it has no effect to specify it when calling selectmenu().
    It seems it's not possible to link directly to the javascript on the site so here's some code to illustrate:

    defaults: {
        transferClasses: true,
        style: 'popup', 
        width: null, 
        menuWidth: null, 
        handleWidth: 26, 
        maxHeight: null,
        icons: null, 
        format: null
    }
    
    _refreshPosition: function(){   
        //set left value
        this.list.css('left', this.newelement.offset().left);
    
        //set top value
        var menuTop = this.newelement.offset().top;
        var scrolledAmt = this.list[0].scrollTop;
        this.list.find('li:lt('+this._selectedIndex()+')').each(function(){
            scrolledAmt -= $(this).outerHeight();
        });
    
        if(this.newelement.is('.'+this.widgetBaseClass+'-popup')){
            menuTop+=scrolledAmt; 
            this.list.css('top', menuTop); 
        }   
        else { 
            menuTop += this.newelement.height();
            this.list.css('top', menuTop); 
        }
    }
    

    I was able to make it work as I first described with the version from github. In my opinion it is a more recent/complete version. Besides it was updated a few days ago.

    I have created a small test page with two selects. I've changed for both the position for the dropdown to show above.
    The first one does not specify the collision option, thus 'flip' is used and the dropdown displays below because there is not enough space above.
    The second has 'none' specified and the dropdown shows above even if there is not enough space.

    I've put the small test project on my dropbox.

提交回复
热议问题