Chosen: Chosen gets "cut" when placed in area with "overflow:hidden".

Created on 27 Jul 2011  ·  128Comments  ·  Source: harvesthq/chosen

I have a div with a form. The div has "overflow:hidden" option in the css.
When Chosen gets created, and it goes below the bottom line of the div, it gets cut.

Here is a screenshot:

Imgur

Bug

Most helpful comment

.chosen-container.chosen-with-drop .chosen-drop {
    position: relative;
}

All 128 comments

This is the same as issue #59

Isn't this unavoidable since the container element, is well, "overflow :hidden" that's just how CSS works. The only way around this is to render the drop down outside of the container and then use absolute positioning.

Yeah, I agree with dfischer. Doesn't seem like a Chosen issue. By definition, the overflow property specifies what happens if content overflows an element's boundaries. If you don't want it the _overflow_ to be hidden, then change that property.

While true, I think this is a common use case with dialog boxes. (Especially jquery dialog)

It is a common use case, however based on this ticket, like I previously mentioned... the entire structure and implementation has to change if you want to accomplish this.

You are _required_ to render outside of the container for this to happen and then use jQuery/JS magic to figure out the positioning relative to the trigger.

jQuery Dialog's case doesn't depend upon a container element so it just uses positioning based on center dimensions and width of the dialog.

This is more of a CSS issue, not a Chosen issue. Don't put overflow: hidden on the container. You're going to have to use another technique to clear the floats below it if that's what you're doing.

I just wrote some code which I think does what you're looking for:

$.fn.extend({
chosen: function (data, options) {
if ($(this).parent().css("overflow") == "hidden") {
//get the offsets between parent and child to calculate the diff
//when we push to absolute
var y = $(this).offset().top - $(this).parent().offset().top,
x = $(this).offset().left - $(this).parent().offset().left,
$t1 = $("<div/>", {
css: {
"position": "relative",
"height": $(this).parent().height,
"width": $(this).parent().width
}
}),
$t2 = $("<div/>", {
css: {
"position": "absolute",
"top": y,
"left": x
}
});
$t1.insertBefore($(this).parent());
$(this).parent().appendTo($t1);
$t2.appendTo($t1);
$(this).appendTo($t2);
}
return $(this).each(function (input_field) {
if (!($(this)).hasClass("chzn-done")) {
return new Chosen(this, data, options);
}
});
}
});

(btw I'm new to github as of today so if there is a different place where I should be posting code let me know)

That code effectively does the following:

  1. calculate the offset between the select box and the parent.
  2. create a parent div with the same dimensions as your overflow hidden and set to relative.
  3. create a parent for the select box creating the element as absolute using the x and y offsets from step 1.
  4. insert new parent before the select's parent, append the overflow div inside of the new parent, append that new select parent inside of the master parent, append the select to the new child parent.

Interesting idea Matthew, but I think that's not going to work in a jQuery-UI dialog is it?

It's more likely that the dropdown element (.chzn-drop) needs to be pulled out of the .chzn-container and up to the document body...

Just add a style to the page and your answer is yes:

.ui-dialog{ overflow:visible; }

Doesn't work for me, since I create my pages using div's as columns (as opposed to td's and tables).
I use "overflow:hidden" to stop runaway content from ruining neighbour divs.

I suppose many of you use the same structure.

That won't work, as the dialogs are set to overflow:auto so they can
have scrollbars if necessary.

On Fri, Jul 29, 2011 at 11:47 PM, ethaniel
[email protected]
wrote:

Doesn't work for me, since I create my pages using div's as columns (as opposed to td's and tables).
I use "overflow:hidden" to stop runaway content from ruining neighbour divs.

I suppose many of you use the same structure.

Reply to this email directly or view it on GitHub:
https://github.com/harvesthq/chosen/issues/86#issuecomment-1681303

Before we get any further into this conversation, what I've done is a theoretical fix. It can't be applied to all scenarios because all it takes is one element having a counter-attribute to screw it up. The above solution with the overflow visible will only work with dialog option resizable:false. Why would you need to have a select overflow outside of a dialog?

Ok, here are a bunch of screenshots which hopefully clarify the issue.

http://i.imgur.com/9ZY9O.png
http://i.imgur.com/c2PLo.png
http://i.imgur.com/1oqZ7.png
http://i.imgur.com/ZBrQj.png

Screenshots 1 & 2 show how it behaves, there isn't enough space for
the dropdown "inside" the dialog, so it scrolls and is hidden as a
result. This is very clunky to use and ugly and not how the built in
select controls work (they show over the top of the content, no matter
how deep inside it they are or what it's overflow style is.)

Screenshots 3 & 4 show my current work-around, which is to put a whole
heap of space below the dropdown. This is also ugly and makes the form
harder to use.

So, to summarise, the real point is that native select controls aren't
restricted to their parent container and if it's possible, the chosen
enhanced select control shouldn't be either, since it's designed to be
a drop-in replacement for the native control.

This theoretically can be done but it would require a completely different construction/positioning system by the chosen plugin. This change would be extensive and require about a 30% rewrite of the current plugin. I consider this a feature request and not a bug. All browsers have a default render for select elements.Chosen replicates it using divs but is not treated like a select element.

Like I said, the only way to do this is absolute positioning OUTSIDE of the triggered element. There's no other way. Correct on @medelbrock

While it would be very nice to have chosen behave like a browser widget, I agree this should be considered a feature not a bug. Can we currently set a max height?

@veloper: I gave that a go (as best I could) and it didn't seem to help. I can't see how it would work either, as the div.chzn-drop is still contained in the dialog, so will be clipped regardless of whether it is absolutely positioned or not.

The only way to stop that is going to be to pull the div.chzn-drop out of the dialog and make it a child of <body>, but as everyone is pointing out, that is a bigger change than anyone is willing to get their hands dirty trying.

Unfortunately using overflow:visible isn't an option, the dialog needs to be scrollable if necessary.

I think I've solved the issue by setting the drop down position to absolute and whenever showing the drop down setting it's position.
e.g. Changing (editing the javascript)

this.dropdown.css({
    "top": dd_top + "px",
    "left": 0
});

to

var parent = this.dropdown.parent();
var offset = parent.offset();
dd_top = offset.top + parent.outerHeight();
dd_width = parent.width();
this.dropdown.css({
    "top": dd_top + "px",
    "left": offset.left,
    "width": dd_width + "px"
});

I'm running into this problem myself while trying to make Chosen work inside a Wijmo / jQuery UI Dialog. I may be way out of my league here, but isn't there a fairly simple fix of making the "dropdown" portion have "display: none" while hidden, and then "display: block" when shown? You'd still incur the scroll bars when the dropdown is open, but that's probably better than having the scroll bars always present.

The fix (tested in Chrome 13, Firefox 7 and IE 9) :

In chosen.css:

.chzn-container .chzn-drop {
position: fixed;
}

and in Chosen.prototype.results_show

var offset = this.container.offset();
this.dropdown.css({
"top": (offset.top+dd_top) + "px",
"left": offset.left + "px",
"display": "block"
});

http://img30.imageshack.us/img30/4094/chosen3.png

That's the stuff, good thinking @levushka. Resolved now in my branch: https://github.com/tompaton/chosen/commit/fda07051161f3fffe6049362b6c9b66ffbe857d1

Ok, it's a little more complicated than that. The above fix didn't work if the page was scrolled.

I've updated my repo with a changeset that sort of fixes it, the dropdown is positioned correctly now, but if the page is scrolled while the dropdown is visible it doesn't move as expected. That's annoying, but not a show stopper.

iOS 5 _might_ solve this, but iOS currently doesn't support position: fixed in the same way that desktop browsers do. Chosen works terrifically on the desktop, but this might limit its uses on poorly designed mobile browsers...

I'm not just picking on Apple here, older version of Android also lack support for position: fixed.

As of jQuery 1.7 (not yet released, but in release candidate) they have a built-in test for CSS Position Fixed support:
http://bugs.jquery.com/ticket/6809

Might be worth detecting jQuery 1.7 and using their result, or copying their code and getting a separate result otherwise.

+1 for position at the end of body element.

check the jquery widget "autocomplete". pretty good solution for that problem:

http://jqueryui.com/demos/autocomplete/

great plugin by the way.

I had this issue mostly in webkit browsers. IE just goes mental with chosen, so i disabled it if ie. Using jquery, i check if the browser is a webkit one, and adjust the overflow of the div containing my chosens like so:

if($.browser.webkit) $(this).css("overflow",($(this).is(":visible"))?"visible":"hidden");

where this is the div containing the chosens.

+1 @levushka and @tompaton Not perfect, but good enough-ish. Barely :)

@levushka solution is great, but it is global ... so at window.top when you scroll down and click to chosen, it roll down in wrong position. So here is solutuion for normal pages and popup windows

in Chosen.prototype.results_show

replace:

  this.dropdown.css({
    "top": dd_top + "px",
    "left": 0
  });

with:

if($('.popup').length!=0) {

  var offset = this.container.offset();
  this.dropdown.css({
    "top": (offset.top+dd_top) + "px",
    "left": offset.left + "px",
    "display": "block"
  });

} else {

  this.dropdown.css({
    "top": dd_top + "px",
    "left": 0
  });

}

CSS:

   .popup .chzn-container .chzn-drop { position:fixed; }

If you are using jQuery UI or something else, you can have problems with z-index, so set chosen z-index to higher values (jQuery UI is it 1010+)

Now it is wokring in FF and for Chrome you need:

     .popup { overflow-x:visible; overflow-y:visible; }

lover elements can have overlow:hidden with no problems.

Why not render the dropdown in the body and use Jquery UI's position function to position the box? http://jqueryui.com/demos/position/. This is the standard method used for many jquery ui widgets.

$( ".czn-drop" ).position({
of: $( "#container" ),
my: "left top",
at: "left bottom",
});

Forgive me for barging in, I had the same problem with displaying chosen drop down in a jQueryUI dialog.
I tried the usual stuff with overflow but this was messing my other dialogs.

What I did instead, was to set my dialog to a fixed height and set the chosen drop down to a fixed height as well.
It would be nice to have an option to do this from chosen's options instead of css.

.chzn-drop {
overflow: auto;
max-height: 75px;
}

Maybe this helps someone else.

Excuse-moi for a quite n00bish/RTFM question, but how can I render the dropdown outside the container (say, on body)? Right now, the only thing that comes to my mind is to fork the plugin and shove that piece of code into it. There must be a more elegant way of achieving this.

Is there an event the choosen fires when the drop down is open/closed. If so, I can just change the overflow setting of the parents divs to visible and then back. I tried that with:

$(".chzn-drop").show(0, function () { 
   $(this).parents("div").css("overflow", "visible");
});    

And, yea, it worked. But, then when I added:

$(".chzn-drop").hide(0, function () {
   $(this).parents("div").css("overflow", "");
});

It no longer worked. I assume because I have several choosen controls on the form. If I could add this code inside an open/close event then I think it would get me where I want to go.

You can listen to the liszt:showing_dropdown and liszt:hiding_dropdown dispatched on the original select element

Excellent... so this solved my issue:

$(".chzn-select").on("liszt:showing_dropdown", function () {
$(this).parents("div").css("overflow", "visible");
});
$(".chzn-select").on("liszt:hiding_dropdown", function () {
$(this).parents("div").css("overflow", "");
});

Of course, it may not work with all layouts.

Thanks... BOb

I've forked the code to make the dropdown child of <body/>. I didn't test it enough yet, but it's working here perfectly -> https://github.com/gil/chosen

Can you see if it solves your problem, @tompaton? I think I just have to detect scrolling now, to fix the position manually.

The fork fixed the display issue for me, and worked well at the bottom of the page where it limited the height it displayed to something reasonable. However, the fork stopped the multi-select functionality from working.

@geoffweatherall Really? Nice! :D About the problem with multi-selection, what stopped working? Could you please try the example.jquery.html file and tell me if it's not working? For me it seems to be okay.

Yes, examples work fine (FF 12).

The single select example is in a fairly plain html page with "panels" that use overflow hidden. However, the multi select example is in a "dialog" created using colorbox (http://www.jacklmoore.com/colorbox) - don't ask me why, the project was like that when I arrived. I guess it might have something to do with that, I will look into it.

The fork fixes the cut-off issue in a number of locations in our application, including multi-selects that are not nested within colorboxes (http://www.jacklmoore.com/colorbox). I believe the issue with colorbox is no fault of chosen. Great fork :-)

Actually I found an issue with the fork that shows in the sample page (example.jquery.html). For the multi select control, if you click in the control to open the list of options, and then use the up arrow and down arrow keys to navigate the list, the list of options makes a surprise move to the top of the page. This issue does not occur for single selects. Tested in FF12, Chrome 18 and IE8.

@geoffweatherall Maybe the problem with the colorbox is that it's being rendered over the Chosen dropdown. Try something like this to see if it helps:

.chzn-drop {
    z-index: 999999 !important;
}

Or try setting the colorbox opacity to 0.1 to check if you can see the dropdown bellow the colorbox.

The other problem, with the keys, I'll try to find some solution. I didn't use the multi-selection in the project I'm working now, so I almost didn't test it. Focused more on the single-selection option.

Ok, I tried this and I did get the drop downs visible, however the position is wrong. They are dropping down below the text box by quite a bit. Here is a jing showing the behavior. http://screencast.com/t/c4PCIHC176RX

Hi Gil,

I've tried your version and it's working! Thank you so much!
There's only one small thing that stopped working.. It's the disable_search_threshold option. The search field won't dissapear.

Have you got any idea?

Thanks!

Nevermind! I managed to fix it myself, however.. maybe you should change that in the code aswell:

Change:

    if (this.form_field.options.length <= this.disable_search_threshold) {
      this.container.addClass("chzn-container-single-nosearch");
    } else {
      this.container.removeClass("chzn-container-single-nosearch");
    }

To

    if (this.form_field.options.length <= this.disable_search_threshold) {
      this.dropdown.addClass("chzn-container-single-nosearch");
    } else {
      this.dropdown.removeClass("chzn-container-single-nosearch");
    }

What's the status of this fork? Has it be merged into master? Or is it still in testing?

One other issue.. the fork seems to work will for me, but in firefox I see the dropdown div at the bottom of the page. It seems that the negative left position doesn't move it out of the display area. Perhaps it is due to some other styles I have... thought. Any idea? Why isn't it's display being set to none?

I made a pull request a long time ago for my original fix but it was
never accepted (no idea why).

There have been a lot of additional tweaks suggested in this thread
since then, I haven't played with any of them yet, and haven't checked
to see if someone has a fork which incorporates them (if there isn't
one, someone should create one, and if there is, that would be a good
answer to your question.)

On Thu, Jun 7, 2012 at 6:44 AM, Bob Archer
[email protected]
wrote:

One other issue.. the fork seems to work will for me, but in firefox I see the dropdown div at the bottom of the page. It seems that the negative left position doesn't move it out of the display area. Perhaps it is due to some other styles I have... thought. Any idea? Why isn't it's display being set to none?


Reply to this email directly or view it on GitHub:
https://github.com/harvesthq/chosen/issues/86#issuecomment-6162299

I tried them all, and none of them worked for me, because I have multiple fieldsets that are hidden and a long form that scrolls. So, my solution was to make the dropdown static and hidden initially, and shown when opened, which stretches the parent container. This works in all of my forms, even if it's at the very bottom of the screen.

in Chosen.prototype.results_show:

      this.dropdown.css({
        "top": dd_top + "px",
        "left": 0,
        "display": "block"
      });

In Chosen.prototype.results_hide:

      this.dropdown.css({
        "left": "-9000px",
        "display": "none"
      });

in chosen.css:

.chzn-container .chzn-drop {
  position: static;
  display: none;
}

@gil, I just want to say thank you for your fork, I was about to give up on using Chosen for my project because of this bug.

I'm honestly quite surprised that the harvest guys don't see the flaw inherent in binding a floating popup to a constrained container. Even regardless of overflow rules, that's just not a good idea for a public library that has no idea what people may be doing around the widget.

Hey guys! It's nice to know my fork is helping some people with this problem... :)

I don't know if they are planning to change the code or merge with some of the solutions proposed here. We don't know if we can assume that this is the best solution for all cases. Let's keep testing and maybe send a pull request with all changes.

@geoffweatherall I've fixed the code with something I think will help you with the keyboard problem. Please tell me if it works! ;)

@PilotBob Do you still have the problem from that jing? About the other issue, I've tested example.jquery.html on Firefox 12 and it seems to be fine. Maybe you can try to replace all left:-9000px you can find by display:none. I don't know the code well enough to tell you, but since I'm settings display:block at results_show(), it might help you.

@pruimmartin Thank you for your fix and sorry for taking too long to reply. I've already merged the fix on my code!

gil - no it doesn't seem to be happening any more, and I didn't change anything. I expect there may have been a js error elsewhere that was causing it. However, I have other issues with chosen and I have been considering replacing it with something else. This is mainly because the lack of updates being done on the master.

@PilotBob I'm considering this project: https://github.com/ivaynberg/select2
They have the same overflow issue, but I think they are planning to change on version 3.

@gil - Your solution works great, but with width of li.search-field stays fixed at 25px. In other words, when I load your example page, the menus are beautifully appended to the body element, but the placeholder text and any typing are constrained to 25px wide. In fact, it looks like the search_field_scale method isn't there at all. Am I missing something here?

@rreusser I've removed the method search_field_scale, since it was only used for multi selection and to calculate the position correctly. That wasn't necessary for this fork anymore. What browser/version/OS are you testing? For me the search field size is correct at example.jquery.html.

@rreusser Hey, sorry. Now I see what's wrong. I'll try to fix it later today.

No problem, @gil! Thanks for the prompt reply! I need to do some more experimenting, but it might also be useful to allow attachment to an arbitrary element—which should also be pretty trivial, I think. I have a select box inside a scrolling div, and while your solution prevents clipping, the menu doesn't move with the div when scrolled. I think all that's necessary is one extra div somewhere, but this is gonna take some tinkering.

@rreusser I've reverted that commit and fixed the problem I was trying to fix differently. Could you please try again and tell me if it works for you?

And about attaching to a different element, I was thinking about making it configurable. But you can solve your scrolling problem with a little config. When your <select /> is not direct children of your scrolling div, try this:

$(".your-select").chosen({
    overflow_container: $(".scrolling-div")
});

But if your <select />'s parent node was your <div />, this shouldn't be necessary.

@gil, Will this fork be merged to master? Or is it still in testing? I also had an issue with keyboard controls in the fork, the down arrow key does not fire the results_show or results_toggle methods. Thanks :-)

@myfriendtodd I don't know yet, maybe I could send a Pull Request when everyone think it's stable. But I still think it needs more testing. I'll try to fix the keyboard issues this weekend. Thanks!

@myfriendtodd Hey, I think I've fixed it. Could you please test it on your project? ;)

thanks @gil will let you know how it turns out. thanks for all your help :-)

@gil Thanks very much for your fork. The fix worked beautifully for me - awesome!

However, I am using the Kickstrap to style Chosen to fit into Twitter Bootstrap. This results in Chosen with this fix being very badly broken - the contents of the dropdown appear at the bottom of the page, unstyled - https://skitch.com/dyad/euys2/login . As far as I know all Kickstrap does is over-write the default Chosen styles.

The LESS file for the changes made to the styling can be found at https://github.com/ajkochanowicz/Kickstrap/blob/master/extras/chosen/chosen.less - is there anything obvious that your fix edits that explains why this might be happening?

Thanks very much indeed.

Hey guys,

I'm working on a new version with a different approach, instead of appending the dropdown to the body. This version is a lot cleaner and will hopefully reduce many bugs, since the change is not that big. Can you guys try it out to see if it works? It's on a new branch:

https://github.com/gil/chosen/tree/new_version

@conatus Can you please try with this version too? Last version on branch "master" had many changes on the css file, this version change just 3 lines. Change these on Kickstrap's Chosen css:

  • Line 4, change from "position: relative;" to "position: static;".
  • Line 13 change from "position: absolute;" to "position: fixed;".
  • On line 128, insert a new line "display: none;", below the "left: -9000px;"

I hope this will make it work! ;)

Also, this new version is in sync with harvesthq's master branch!

Sorry I didn't follow up before but we got onto a different part of the project and this faded into the distance very quickly! I'll test it out and let you know as soon as I get a chance though. Thanks so much for your continued effort!

@gil - I am testing Your version and while it works great, there is a small issue: when chosen is placed inside a fixed-position element, then scrolling the page will displace the dropdown. This is actually an issue with the jQuery Autocomplete as well.

I can only think of 2 possible solutions to this:
1) If chosen is placed inside a fixed-positioned element, the dropdown should be placed inside chzn-container and be given a fixed position as well. The top position should be calculated by the container's fixed position
2) Re-calculate the dropdown position while scrolling

The third option is to make the dropdown fixed any time the select is in a fixed position container.

@ragulka @ChiperSoft I see the problem... Just to make sure, is this jsfiddle reproducing what you guys are saying? http://jsfiddle.net/QY256/

I'll try to do something about it. There's a new option called overflow_container that will handle scrolling problems, as you can see when you scroll just the div. But the problem here is when you scroll the window, it will be positioned incorrectly.

I was thinking about making Chosen close, when something scrolls, since handling the scroll causes some other minor problems (like when your <select /> is only half visible).

@ragulka @ChiperSoft Also, as a temporary fix, can you guys try to change line 640, inside update_position method, from:

"top": (offset.top + dd_top) + "px",

to:

"top": (offset.top + dd_top - $(window).scrollTop()) + "px", ?

@gil Yes and no - the jsfiddle you provided does show the problem, but for me it appeared when I was scrolling the body (my fixed element did not have any scrollbars). In Your jsfiddle the problem seems to appear when I am scrolling the contents of the fixed element, but not when scrolling the body.

@ragulka I know it's not the best solution, but I think I've fixed it here. Can you try it? Make the change in line 640, like I said, and apply Chosen like this:

$(".your-select").chosen({
    overflow_container: $(".your-fixed-div").add( document )
});

This should handle scroll on the div and on document, and fix the position.

But like I said, I think I'll change this later to make Chosen hide when the user scrolls something.

This may not be a chosen bug, but I switched to select2 as a drop in replacement for chosen and the issue went away without needing to do any workarounds.

Thanks very much for that.

In the intervening time Kickstrap updated - https://github.com/ajkochanowicz/Kickstrap/blob/beta/assets/Kickstrap/apps/chosen/chosen.css. Your new branch works wonderfully, however the changes you suggest to the Kickstrap CSS don't seem to have the effect. What happens is the drop down itself no longer appears. Any ideas? Thanks a lot.

Thank you @gil!!! Your branch (https://github.com/gil/chosen/tree/new_version) fixed my problem with this particular issue.

Thanks for all the advice. I made some slight modifications to the suggestions above in order to get the dropdowns to work with Bootstrap v2.1.1 modals and Chosen v0.9.11. Small changes were needed to get the .chzn-drop to be positioned correctly once it was reopened after the page was scrolled.

Hope this helps others.

CSS
.modal .chzn-container .chzn-drop {
  position:fixed;
}
Javascript
Chosen.prototype.results_show = function() {

      var self = this;

      // hide .chzn-drop when the window resizes else it will stay fixed with previous top and left coordinates
      $(window).resize(function() {
        self.results_hide();
      });

      var dd_top;
      if (!this.is_multiple) {
        this.selected_item.addClass("chzn-single-with-drop");
        if (this.result_single_selected) {
          this.result_do_highlight(this.result_single_selected);
        }
      } else if (this.max_selected_options <= this.choices) {
        this.form_field_jq.trigger("liszt:maxselected", {
          chosen: this
        });
        return false;
      }
      dd_top = this.is_multiple ? this.container.height() : this.container.height() - 1;
      this.form_field_jq.trigger("liszt:showing_dropdown", {
        chosen: this
      });

      if($('.modal.in').length) {
        // when in a modal get the scroll distance and apply to top of .chzn-drop
        var offset = this.container.offset();
        var scrolly = parseInt($(window).scrollTop(), 10);
        scrolly = scrolly < 0 ? 0 : scrolly;
        var toppy = offset.top+ dd_top - scrolly;
        this.dropdown.css({
          "top": toppy + "px",
          "left": offset.left + "px"
        });
      } else {
        // proceed as normal
        this.dropdown.css({
          "top": dd_top + "px",
          "left": 0
        });
      }

      this.results_showing = true;
      this.search_field.focus();
      this.search_field.val(this.search_field.val());
      return this.winnow_results();
    };

So i was playing a little bit with Chosen 0.9.11 and i identified the changes i needed to do on Chosen...

Im using Chosen inside a heavily modified jQueryUI Dialog which is draggable and has a maximum height with overflow: scroll.

To get Chosen to behave like i want i changed ".chzn-container .chzn-drop" to "position:fixed" and added "display:none". Then in "Chosen.prototype.results_hide" i added "display:none" to "this.dropdown.css"...

this.dropdown.css({
    "left": "-9000px",
    "display": "none"
});

And in "Chosen.prototype.results_show" i replaced the content of "this.dropdown.css" with "display:block".
To get the right position of the .chzn-drop div i've added the jQueryUI position function.

this.dropdown.css({
    "display": "block"
}).position({ my: 'left top-1', at: 'left bottom', of: this.container, collision: 'fit',  });

In "Chosen.prototype.search_field_scale" change...

return this.dropdown.css({
    "top": dd_top + "px"
});

... to ...

return this.dropdown.position({ my: 'left top-1', at: 'left bottom', of: this.container, collision: 'fit',  });

Now i have only one problem left:

I need to listen to the jQuery UI Dialog drag events to close the Chosen drop when someone start to move the dialog arround. I already achieved this but the code is pretty dirty :-)

Is there any chance the non-trivial fix from this branch https://github.com/gil/chosen/commits/new_version gets ported to GWTChosen?
GWTChosen is awesome. However, in current state it cannot be used with LayoutPanels at all.

How about adding a new feature to Chosen library where list would be rendered above the text field simply by adding different or a new class? This way script doesn't have to render the list outside of the wrapping overflow:hidden div, and would probably solve most of the issues others have. PS: I don't consider this as an issue as overflow:hidden does exactly what is suppose to be doing. It's more of nice to have feature. Thanks.

+1 To Klikerko's suggestion.

Just as @sillysachin I use GWTChosen and I have the same issue with LayoutPanels, overflow:hidden and ChosenListBox :/

Does anyone know of a fix for this? @sillysachin have you come up with something since you posted here?

Tnx in advance :)

We have sort of patched it ad-hoc by pulling the dropdown div out of the parent container. Unfortunately i am swamped with release crush and will take time to cleanup the patch before submitting it here.

This commit in https://github.com/tompaton/chosen/commit/3d9be332de23bfe69d53c7640e829e879e084983 fixes it reasonably well. It is relatively up to date, but I did it for jQuery only.

@robmcguinness I had to modify it some to work. However, it creates a bug. where you can not Close the dropdown.

 Chosen.prototype.results_show = function() {

 this.dropdown.css({
      "display": 'block'
    });

  var dd_top;
  $(window).resize(function() {
    this.results_hide();
  });

  if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
    this.form_field_jq.trigger("chosen:maxselected", {
      chosen: this
    });
    return false;
  }

  dd_top = this.is_multiple ? this.container.height() : this.container.height() - 1;
  this.container.addClass("chosen-with-drop");
  this.form_field_jq.trigger("chosen:showing_dropdown", {
    chosen: this
  });

  if($('.modal.in').length) {
    // when in a modal get the scroll distance and apply to top of .chzn-drop
    var offset = this.container.offset();
    var scrolly = parseInt($(window).scrollTop(), 10);
    scrolly = scrolly < 0 ? 0 : scrolly;
    var toppy = offset.top+ dd_top - scrolly;
    this.dropdown.css({"top": toppy + "px","left": offset.left + "px"});
  } else {
    // proceed as normal
    this.dropdown.css({
      "top": dd_top + "px",
      "left": 0
    });
  }




  this.results_showing = true;
  this.search_field.focus();
  this.search_field.val(this.search_field.val());
  return this.winnow_results();
};


Chosen.prototype.results_hide = function() {
  if (this.results_showing) {

    this.dropdown.css({
      "display": 'none'
    });

    this.result_clear_highlight();
    this.container.removeClass("chosen-with-drop");
    this.form_field_jq.trigger("chosen:hiding_dropdown", {
      chosen: this
    });
  }
  return this.results_showing = false;
};

and I had to add a width to the CSS, otherwise it would go 100% width of the site.

.modal .chosen-container .chosen-drop {
position:fixed;
width: 300px;
}

I was able to fix the issues with the above code. Compatible with version 1. However, mine is more of a rig for it to work. but so far it is working right. The last issue i see is resizing the browser, the current mod doesnt work.

Anyone knows if any of the possible fixes to this problem are going to be merged into the master branch soon? This is a deal-breaker for me =/.

We moved on to using Select2... it has more features too.

On Thu, Dec 19, 2013 at 11:24 AM, Daniel Hoffmann Bernardes <
[email protected]> wrote:

Anyone knows if any of the possible fixes to this problem are going to be
merged into the master branch soon? This is a deal-breaker for me =/.


Reply to this email directly or view it on GitHubhttps://github.com/harvesthq/chosen/issues/86#issuecomment-30942420
.

Thank you PilotBob, is chosen no longer maintained? If so you might want to update the documentation.

It's not my project. I "was" a user of it. Due to several issues we found
an alternative.

On Thu, Dec 19, 2013 at 11:53 AM, Daniel Hoffmann Bernardes <
[email protected]> wrote:

Thank you PilotBob, is chosen no longer maintained? If so you might want
to update the documentation.


Reply to this email directly or view it on GitHubhttps://github.com/harvesthq/chosen/issues/86#issuecomment-30945150
.

@DanielHoffmann Chosen is still actively maintained. Select2 was originally a fork of Chosen, but has since gotten far enough away that it is it's own thing.

Chosen is intentionally kept simple -- it was intended to be a drop-in replacement for selects, so it avoids a lot of complicated features and configs. Select2 took the opposite route, and added many, many features and configs -- it's up to you which of those philosophies you value more.

As for this _specific_ issue, it is unfortunately just that: an issue, not a fix. If someone submits a pull request to fix it, it would be considered for merging. However, OSS is not the primary job of any of the maintainers -- they work on it when they can around their full-time jobs. So, as always, "pull requests accepted" if you want to try to fix it yourself!

when is this issue going to be fixed? it is so old but critical to a lot of projects! please address it ASAP!

thanks!

there are a lot of fixes in the forks of chosen so why do not use one of those fixes?

@domnulnopcea There has never been any PR submitting a fix for this, only duplicate reports. If you have an idea to fix it, please send a PR. We will then review it. Currently, I'm not aware of any fork fixing this particular issue

I have a fix for this, its not a clean fork, its buried in another repository and its only on the jQuery version. (No I'm not proud of my self)

It works by adding the drop down element to the body element and setting its position absolutely when the page is scrolled or resized. It also works out if the drop down should be above or below the field and how tall it should be (so its not cut off by the page).

If this is something you are interested in merging in (and there are indeed no other forks) I will try and find some time to dust it off and create a pull a request.

https://gist.github.com/msaspence/11032254

@domnulnopcea this has never been submitted for inclusion into Chosen itself AFAIK. We cannot loo at all forks to examine all work done on it. We are working on Chosen on our free time, so we cannot dedicate weeks at examining thousands of commits in many repos to see what they are doing

@stof we appreciate your work very much. I use it on my own project (www.ubirimi.com) But now that I have given you a link to a commit would you be so kind to look into those changes and apply them to the official chosen repository?

thanks a lot

Given that it cannot be applied directly (the code has changed a lot since 11 months), it will require some time (and it also requires testing it to be sure it works properly). So I cannot do it now

@stof thanks for thinking about doing it! I appreciate it!

@domnulnopcea if its that important to you why don't you go over the changes and create a pull request yourself. This is the beauty of open source after all

@msaspence I would but I am not a frontend developer! I am not very used to JS and all that client side stuff

We moved on to Select2 since it allows for AJAX data retrieval. You guys might want to look at it.

I think everyone has moved to Select2 at this stage - is there any advantage to using Chosen?

For me worked perfectly the PilotBob solution!

I added this on my code:

$(document).ready(function () {
$(".chzn-select").on("liszt:showing_dropdown", function () {
$(this).parents("div").css("overflow", "visible");
});
}

Thank you very much!!!

The problems is that the position of the list of options is absolute, it not expand the parent container. A solution that I propose is change it to float: left | right because it can expand the parent, if after I add a DOM object with clear:both

I solved this (used with jquery-ui dialog) with the following in my css:

#clone-budget-dialog {overflow: visible;}

@grduggan can you propose a solution in the css of the library?
I think that your solution is valid. Make a push-request!
+1

Never done that before. I'll have to investigate. It would be nice to have in the css.

I see a similar issue when the select box is close to the end of the page. The native select box solves this just opening up instead of dropping down. Why not?

overflow: visible; on container's div worked for me! Thanks.

you don't always need the overflow:hidden when you use floats, you can also clear floats using this in your parent (remove the overflow:hidden):

&:before,
&:after {
content: " "; // 1
display: table; // 2
}
&:after {
clear: both;
}

that's how clearfix class works in bootstrap

I modified the css (see below). Seemed to work for my scenario.

.chosen-container .chosen-drop {
position: relative; /_Changed from absolute to avoid overflow cutoff in container_/
top: 100%;
left: -9999px;
z-index: 1010;
width: 100%;
border: 1px solid #aaa;
border-top: 0;
background: #fff;
box-shadow: 0px 4px 5px rgba(0,0,0,0.15);
}

.chosen-container .chosen-results {
color: #444;
position: relative;
overflow-x: hidden;
overflow-y: auto;
margin: 0 4px 4px 0;
padding: 0 0 0 4px;
max-height: 200px; /_Changed from 240px_/
-webkit-overflow-scrolling: touch;

/*Added to clearfix because we changed the chosen-drop to a relative position*/
&:before,
&:after {
    content: " "; // 1
    display: table; // 2
}
&:after {
    clear: both;
}

}

Wrapping the select (and Chosen) in a fieldset element can also produce unwanted effects in webkit browsers (i.e. cutting of when a parent has overflow: hidden).
This is because webkit adds min-width: -webkit-min-content; to fieldsets by default.

This solved the problem for me:

fieldset { min-width: 0; }

@chassq hmm your solution doesn't work for me, .. see this screenshot:

image

I have a div around the chosen selects with

  max-height: 200px;
  overflow-y: auto;
  overflow-x: hidden;

Thanks to all which already gave the solution with position: fixed

Here is a jsfiddle with the solution (overwrites chosen CSS classes):
http://jsfiddle.net/jwbL8utx/1/ ;)

I still have 1 problem, when scrolling down (using max-height) the chosen has an offset, as you can see here when scrolling down and opening the second chosen:

http://jsfiddle.net/jwbL8utx/2/

This is how I solved it:

http://jsfiddle.net/0w4a4dq5/1/

This fix doesn't require you to change any other elements besides the chosen menu itself. You'll notice It hides the menu again if you 'un-hover' it, but this is as per my requirement. If you want to keep it on top all the time, you can bind a scroll event to your div container and trigger the 'chosen:close.chosen' event.

@typologist Thanks for your excellent solution.
There are two minor bugs in your JS I would like to mention though:
In line 51, it should be

'top': y - $(document).scrollTop()

otherwise the popup can be displaced under certain conditions

In line 23, instead of using

$('.chosen-container')

to bind the events, I think it would be better to use

$chosenSelect.next('.chosen-container')

in order to avoid multiple binds if the function is called more than once with different chosen() Widgets to fix.

please tell me is there any solution for Chosen v1.4.2?

.chosen-container.chosen-with-drop .chosen-drop {
    position: relative;
}

overflow-y: visible

Add this to the parent div which is containing the layout. In my case it was a Modal dialog sub div which had _overflow-y: auto_ and replacing it with _overflow-y: visible_ worked for me.

Is there a solution to this problem yet?

This project have your response:
http://jsbin.com/finufihaji/edit?html

Looking for a little and doing tests is the most basic solution.

I had to override the .chosen-drop and .chosen-results and set a fixed height to both in order that all options as selectable and not affected by the parent div overflow directive

At least this works for me and most of my chosen field only have 3 or 4 options. Only 1 (the one being hidden) has around 12 and can grow in the near future.

I applied the following to the parent div that had the overflow: hidden

.profile-content { /* Hack to stop profile-content from cropping Chosen dropdown */ padding-bottom: 100px; margin-bottom: -100px; }

Source: Stack Overflow

@doowruc Great hack!

Is there a method for attaching the chosen dropdown to a specific target, so we could attach it to the document body instead of a dialog? this way chosen flows out of the dialog and is not contained by it?

.ui-dialog-content{
    overflow:visible !important;
 }

Worked for me.

I know that I was still struggling with this. Here is a Fiddle that shows an option for moving the element into the body and setting absolute positioning reliably, even with scrolling.

https://jsfiddle.net/phil_ayres/gvn8bkaL/

https://github.com/R1p8p8e8r/chosen
I think my solution will help you

Was this page helpful?
0 / 5 - 0 ratings