Open JAStanton opened 13 years ago
+1
+1
+1
+1
Wrote a little function into it, works perfect for pagination now http://jsfiddle.net/adamelevate/WFejY/
Mine is driven off of a css class on the select box, so it still isn't dynamic, sry....
+1
+1
+1
This is a must-have feature
+1
still not fixed yet?
+1. In our case, Chosen is placed at the bottom of a modal dialog, and is causing a "phantom" vertical scrollbar to show. So need Chosen to appear above when it is at the bottom of a viewport (not just page).
I've successfully avoided this by making sure that all parent elements have overflow:visible.
+1 fixed on my project like this
#selectId_chzn .chzn-drop {
bottom: 20px;
top: auto !important;
}
but I hope you can do this automatically
So nobody has figured out a way to deal with this that involved intelligent edge detection? My project doesn't afford me the luxury of concretely identifying Chosen elements based on a container that is guaranteed to induce overflow. I have given a little thought to how to get Chosen to recognize if there's room to expand downward, and if not, apply a style similar to what @coldman333 suggested, and haven't figured out a great or reliable way to do it, yet. It would also need to give the dropdown list a border-top
and remove its border-bottom
, to keep the styles consistent. Perhaps it should just apply a special CSS class instead, using jQuery's addClass()
to save processing power.
+1
Okay, I've got a working solution, but it's just kinda hacked up in the compiled javascript file. I'll paste the code here though if anyone want's to create a pull request from it.
If it detects that the dropdown will extend below the window, it will resize it and add a scrollbar, but still drop DOWN. UNLESS there is less than 100px between the dropdown and the window, then it will add a chzn-above
class to the dropdown and show it above the input.
/chosen/chosen.jquery.js [around line 326]
this.search_results = this.container.find('ul.chzn-results').first();
// Start additional code
this.search_results.data('initialMaxHeight', this.search_results.css('max-height'));
// End additional code
this.search_field_scale();
[around line 568]
Chosen.prototype.results_show = function() {
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);
}
}
dd_top = this.is_multiple ? this.container.height() : this.container.height() - 1;
this.dropdown.css({
"top": dd_top + "px",
"left": 0
});
// Start additional code
this.search_results.css('max-height', 'none');
var windowHeight = $(window).height() + $('html').scrollTop(),
dropdownHeight = this.dropdown.height(),
dropdownTop = Math.ceil(this.dropdown.offset().top),
totalHeight = dropdownHeight + dropdownTop;
if (totalHeight > windowHeight) {
var difference = totalHeight - windowHeight,
height = dropdownHeight - difference;
if (height > 100) {
this.search_results.css('max-height', height);
} else {
this.dropdown.addClass('chzn-above');
this.search_results.css('max-height', this.search_results.data('initialMaxHeight'));
}
} else {
this.search_results.css('max-height', this.search_results.data('initialMaxHeight'));
}
// End additional code
this.results_showing = true;
this.search_field.focus();
this.search_field.val(this.search_field.val());
return this.winnow_results();
};
/chosen/chosen.css
/* Add this rule */
.chzn-container .chzn-drop.chzn-above {
top:auto !important;
bottom:29px;
border:solid #aaa;
border-width:1px 1px 0 1px;
}
牛逼
+1
Hi, This issue is fixed. But in the case of chzn-select-deselect option is not working for this feature. Please check this.
Thanks, Sathish Babu
+1
I can’t see the fix in the examples…
I wanted to let my dropdown list 'drop up'. I fixed my issue by changing the top
for .chzn-drop
to the negative value of the max-height
of chzn-results
. Also changed max-height
to just height
else it produces an empty space if there aren't enough results in the drop list. It's an ugly fix I know, but it worked for me.
p.s. Changing the styling a bit is required. For example: the border will be missing on the top and needs to be removed on the bottom of the drop list.
Please work on #1330 so this can be resolved! Ran into this bad bug in our app -- chosen is just non-functional when placed near the bottom edge of the screen.
+1
lot of +1
+1
+1
+1 anyone with a working solution yet?
+1
guys, seems like huge demand, whats up?
Hi!
Add this to the CSS file:
.chosen-container-active.chosen-with-dropup .chosen-single{
-moz-border-radius-topright: 0 !important;
border-top-right-radius: 0 !important;
-moz-border-radius-topleft: 0 !important;
border-top-left-radius: 0 !important;
}
.chosen-dropup {
top: auto !important;
bottom: 23px;
border: solid #aaa;
border-width: 1px 1px 0 1px;
margin-top: -1px;
border-radius: 4px 4px 0px 0px !important;
}
Then modify the JS file:
Find Chosen.prototype.results_hide = function()
then add this:
this.container.removeClass("chosen-with-drop");
//Added by Fenistil
this.container.removeClass("chosen-with-dropup");
//End
this.form_field_jq.trigger("chosen:hiding_dropdown", {
Find Chosen.prototype.close_field = function()
then add this:
this.container.removeClass("chosen-container-active");
//Added by Fenistil
this.container.removeClass("chosen-with-dropup");
//End
this.clear_backstroke();
Find Chosen.prototype.activate_field = function()
then add this:
this.container.addClass("chosen-container-active");
//Added by Fenistil
var windowHeight = $(window).height() + $('html').scrollTop(),
totalHeight = this.dropdown.height() + Math.ceil(this.dropdown.offset().top);
if (totalHeight > windowHeight) {
this.container.addClass("chosen-with-dropup");
this.dropdown.addClass('chosen-dropup');
}
//End
this.active_field = true;
Find Chosen.prototype.results_show = function()
then add this:
this.container.addClass("chosen-with-drop");
//Added by Fenistil
var windowHeight = $(window).height() + $('html').scrollTop(),
totalHeight = this.dropdown.height() + Math.ceil(this.dropdown.offset().top);
if (totalHeight > windowHeight) {
this.container.addClass("chosen-with-dropup");
this.dropdown.addClass('chosen-dropup');
}
//End
this.results_showing = true;
this.search_field.focus();
Greetings!
PS.: Thanks to coreyworrell, this is based on his code.
UPDATE:
Hey thanks for this solution @fenisteel. This works well only with one little exception. It calculates whether to drop up or down based on the window height, not the scroll position.. It is not dynamic as the bootstrap select. For example on page load, user is on the top of the page, chosen at the bottom of the page will dropup. But if the user, scroll down the page, which eventually creates more space for that bottom chosen, it should then drop down as usual
http://silviomoreto.github.io/bootstrap-select/
When you scroll the page up and down, the dropdown should open-up or down based on the new positions not the positions on page load.
Thanks @fenisteel. It's great to see that after three years have a decent solution.
Why there is no dynamic solutions after all the years? I like the control very much except this problem.
Thanks @fenisteel. Your solution works great and very clear instructions on what needed to be changed.
@fenisteel can you send a PR with your changes ?
+1 to a PR from @fenisteel. I use Chosen via Bower in production, and can't edit library files in the repository.
+1 wish this could get out asap in v1.3.1
I've turned the changes by @fenisteel into a PR, see https://github.com/harvesthq/chosen/pull/2312.
This works for me
jQuery('.chosen-single').click(function() {
var $chosePosition = this.getBoundingClientRect(),
$choseDropListHeight = $(this).next().outerHeight();
if($(this).hasClass('above')) $(this).removeClass('above');
if (($chosePosition.bottom + $choseDropListHeight + 10) > $(window).height() && ($chosePosition.top - $choseDropListHeight) > 10) {
$(this).next().addClass("above");
$(this).addClass("above");
}
else {
$(this).next().removeClass("above");
$(this).removeClass("above");
}
$chosensingle = $(this);
$chosenvar = this;
$(window).bind('mousewheel DOMMouseScroll', function(event){
$chosePosition = $chosenvar.getBoundingClientRect(),
$choseDropListHeight = $chosensingle.next().outerHeight();
console.log($chosePosition.bottom + $choseDropListHeight + 10, '-',$(window).height(), '-',$chosePosition.top - $choseDropListHeight);
if (($chosePosition.bottom + $choseDropListHeight + 10) > $(window).height() && ($chosePosition.top - $choseDropListHeight) > 10) {
$chosensingle.next().addClass("above");
$chosensingle.addClass("above");
}
else {
$chosensingle.next().removeClass("above");
$chosensingle.removeClass("above");
}
});
});
@peimn this not worked for me
This was opened how long ago? why hasn't this been a priority to fix?
+1...
+1
+1
Any ETA on this? A much needed feature. I am currently using the solution above, but having to hack it in. It'd be great if this was part of the source.
+1 - this has been an outstanding request for 4 years. Any chance of getting it in there?
+1
+1
I would recommend using Tether.js for positioning the dropdown, it's a much better way because it places it in the body and not where the select
element itself is located, so any overflow:hidden
on a parent element won't clip it. Also, Tether.js is very smart at positioning according to the viewport and you can control everything.
Seems like the author isn't interested in fixing this and I don't like the idea of messing with the core files, so I came up with the below, which uses chosen's events to trigger adding/removing a 'chosen-drop-up' class where appropriate. You can include it anywhere after you've initialised your select(s).
The code is a bit verbose -- deliberately so, so that you can see what's going on.
$('#my-select').on('chosen:showing_dropdown', function(event, params) {
var chosen_container = $( event.target ).next( '.chosen-container' );
var dropdown = chosen_container.find( '.chosen-drop' );
var dropdown_top = dropdown.offset().top - $(window).scrollTop();
var dropdown_height = dropdown.height();
var viewport_height = $(window).height();
if ( dropdown_top + dropdown_height > viewport_height ) {
chosen_container.addClass( 'chosen-drop-up' );
}
});
$('#my-select').on('chosen:hiding_dropdown', function(event, params) {
$( event.target ).next( '.chosen-container' ).removeClass( 'chosen-drop-up' );
});
I haven't posted any CSS because mine is custom so it wouldn't help anyone. But you can start with
.chosen-container.chosen-drop-up .chosen-drop{
top: auto;
bottom: 100%;
}
...which will put the drop-down above the input element. The rest is all about fiddling with borders and so on.
Hope this helps someone.
@Taeon Thank you very much for your solution, it works perfectly! This should really be merged in. Would you submit a pull request? (one more in 80, I know, but still...)
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.