harvesthq / chosen

Deprecated - Chosen is a library for making long, unwieldy select boxes more friendly.
http://harvesthq.github.io/chosen/
Other
21.85k stars 4.1k forks source link

Dropdown at the bottom of the page breaks layout #155

Open JAStanton opened 13 years ago

JAStanton commented 13 years ago

If you have dropdown that's at the bottom of your page. The hidden dropdown menu is pushing the bottom of the page down. That needs to be hidden so that it doesn't effect the styles of the page, it would be nice if the drop down detected the bottom of the page, did a little math to figure out if it has room to expand or not and if it doesn't have room it will switch styles to appearing above and now bellow.

Taeon commented 8 years ago

@claudio-silva : since the author has ignored all related PRs so far I'm not sure there's much point. And anyway, this code is specifically NOT intended to be merged into the core -- it's meant to work without modifying core files. That way it will still work even if I update chosen.

bhubbard commented 8 years ago

+1

nhurion commented 8 years ago

I've implemented the solution proposed by @Taeon (well, more or less, computation is different due to application specific stuff) Here is the css I came up with to make it looks ok. (Not a css pro here)

.chosen-container.chosen-drop-up .chosen-drop {
  border-bottom: 0;
  border-radius: 4px 4px 0 0;
  border-top: 1px solid #aaa;
  bottom: 100%;
  box-shadow: none;
  top: auto;
}

.chosen-container-active.chosen-with-drop.chosen-drop-up .chosen-single {
  background-image: -webkit-gradient(linear,50% 0,50% 100%,color-stop(40%,#eee),color-stop(90%,#fff));
  background-image: -webkit-linear-gradient(#fff 40%,#eee 90%);
  background-image: -moz-linear-gradient(#fff 40%,#eee 90%);
  background-image: -o-linear-gradient(#fff 40%,#eee 90%);
  background-image: linear-gradient(#fff 40%,#eee 90%);
  border-radius: 0 0 4px 4px;
  border-top: 0;
  box-shadow: 0 1px 0 #fff inset;
}
yairEO commented 8 years ago

I've improved upon my excellent peers (above this comment) with a complete solution which uses a little better JS and SCSS to achieve the important goal for countless people worldwide, the despicable maintainer is so happily ignoring:

JS

$('select').on('chosen:showing_dropdown chosen:hiding_dropdown', function(e){
    var chosen_container = $( e.target ).next( '.chosen-container' ),
        classState = e.type == 'chosen:showing_dropdown' && dropdownExceedsBottomViewport();

    function dropdownExceedsBottomViewport(){
        var dropdown        = chosen_container.find( '.chosen-drop' ),
            dropdown_top    = dropdown.offset().top - document.documentElement.scrollTop,
            dropdown_height = dropdown.height(),
            viewport_height = document.documentElement.clientHeight;

        return dropdown_top + dropdown_height > viewport_height;
    }

    chosen_container.toggleClass( 'chosen-drop-up', classState );
});

SCSS

.chosen-container {
    &.chosen-drop-up .chosen-drop {
        border-bottom: 0;
        border-radius: 4px 4px 0 0;
        border-top: 1px solid #aaa;
        bottom: 100%;
        box-shadow: 0 -4px 5px rgba(#000, .15);
        top: auto;
    }
}

.chosen-container-active {
    &.chosen-with-drop {
            .chosen-single:not(.chosen-drop-up) {
                border: 1px solid #aaa;
                border-bottom-right-radius: 0;
                border-bottom-left-radius: 0;
                //background-image:linear-gradient(#eee 20%, #fff 80%);
                //box-shadow: 0 1px 0 #fff inset;
            }
            &.chosen-drop-up{
                .chosen-drop{
                    display:flex;
                    flex-direction: column-reverse;
                }
                .chosen-single {
                    // background-image: linear-gradient(#FFF 40%, #EEE 90%);
                    border-radius: 0 0 4px 4px;
                    border-top: 0;
                    box-shadow: 0 1px 0 #FFF inset;
                    border-top-right-radius: 0;
                    border-top-left-radius: 0;
                }
            }
        }
    }
}
teagis commented 8 years ago

@Taeon his solution works great for me +1

Donny-bsb-dev commented 8 years ago

ok I had the same issue. So I fixed it, may not be the most elegant, but it worked for me. I just added a margin-top: -332px; on .chzn-drop

stecca21 commented 8 years ago

@Taeon Thanks for this code! It saved me a few hours or frustration :)

mikerockett commented 7 years ago

@yairEO - That should totally find its way into the core! Works like a charm!

mikloshenrich commented 7 years ago

@yairEO - Nice solution, but if we have more than one dropdown with this solution, if one of the select dropdowns is triggering an ajax reload, the "chosen-drop-up" class is not added anymore on the chosen list.

Razoxane commented 7 years ago

@Taeon - your solution worked a treat when I changed the ID selector to a class for multiple chosen selects on the page 👍