Bladeren bron

Absolutely position dropdown. fixes #84.

Changes to detach dropdown and append to body, and absolutely position
dropdown. Fixes clipping problems with overflowing.

Signed-off-by: Igor Vaynberg <[email protected]>
Christopher Nadeau 13 jaren geleden
bovenliggende
commit
2f3262d39e
2 gewijzigde bestanden met toevoegingen van 65 en 31 verwijderingen
  1. 18 18
      select2.css
  2. 47 13
      select2.js

+ 18 - 18
select2.css

@@ -13,11 +13,11 @@ Version: @@ver@@ Timestamp: @@timestamp@@
 .select2-container,
 .select2-container,
 .select2-drop,
 .select2-drop,
 .select2-search,
 .select2-search,
-.select2-container .select2-search input{
-  /* 
+.select2-search input{
+  /*
     Force border-box so that % widths fit the parent
     Force border-box so that % widths fit the parent
     container without overlap because of margin/padding.
     container without overlap because of margin/padding.
-    
+
     More Info : http://www.quirksmode.org/css/box.html
     More Info : http://www.quirksmode.org/css/box.html
   */
   */
   -moz-box-sizing: border-box;    /* firefox */
   -moz-box-sizing: border-box;    /* firefox */
@@ -83,7 +83,7 @@ Version: @@ver@@ Timestamp: @@timestamp@@
   cursor: pointer;
   cursor: pointer;
 }
 }
 
 
-.select2-container .select2-drop {
+.select2-drop {
     background: #fff;
     background: #fff;
     border: 1px solid #aaa;
     border: 1px solid #aaa;
     border-top: 0;
     border-top: 0;
@@ -133,7 +133,7 @@ Version: @@ver@@ Timestamp: @@timestamp@@
     height: 100%;
     height: 100%;
 }
 }
 
 
-.select2-container .select2-search {
+.select2-search {
   display: inline-block;
   display: inline-block;
     white-space: nowrap;
     white-space: nowrap;
     z-index: 1010;
     z-index: 1010;
@@ -144,13 +144,13 @@ Version: @@ver@@ Timestamp: @@timestamp@@
   padding-right: 4px;
   padding-right: 4px;
 }
 }
 
 
-.select2-container .select2-search-hidden {
+.select2-search-hidden {
   display: block;
   display: block;
   position: absolute;
   position: absolute;
   left: -10000px;
   left: -10000px;
 }
 }
 
 
-.select2-container .select2-search input {
+.select2-search input {
     background: #fff url('select2.png') no-repeat 100% -22px;
     background: #fff url('select2.png') no-repeat 100% -22px;
     background: url('select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
     background: url('select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
     background: url('select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
     background: url('select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
@@ -172,10 +172,10 @@ Version: @@ver@@ Timestamp: @@timestamp@@
     box-shadow: none;
     box-shadow: none;
     border-radius: 0;
     border-radius: 0;
     -moz-border-radius: 0;
     -moz-border-radius: 0;
-    -webkit-border-radius: 0;  
+    -webkit-border-radius: 0;
 }
 }
 
 
-.select2-container .select2-search input.select2-active {
+.select2-search input.select2-active {
     background: #fff url('spinner.gif') no-repeat 100%;
     background: #fff url('spinner.gif') no-repeat 100%;
     background: url('spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
     background: url('spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
     background: url('spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
     background: url('spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
@@ -228,7 +228,7 @@ Version: @@ver@@ Timestamp: @@timestamp@@
 }
 }
 
 
 /* results */
 /* results */
-.select2-container .select2-results {
+.select2-results {
   margin: 4px 4px 4px 0;
   margin: 4px 4px 4px 0;
   padding: 0 0 0 4px;
   padding: 0 0 0 4px;
   position: relative;
   position: relative;
@@ -236,7 +236,7 @@ Version: @@ver@@ Timestamp: @@timestamp@@
   overflow-y: auto;
   overflow-y: auto;
   max-height: 200px;
   max-height: 200px;
 }
 }
-.select2-container .select2-results li {
+.select2-results li {
   line-height: 80%;
   line-height: 80%;
   padding: 7px 7px 8px;
   padding: 7px 7px 8px;
   margin: 0;
   margin: 0;
@@ -245,37 +245,37 @@ Version: @@ver@@ Timestamp: @@timestamp@@
   display: list-item;
   display: list-item;
 }
 }
 
 
-.select2-container .select2-results .select2-highlighted {
+.select2-results .select2-highlighted {
   background: #3875d7;
   background: #3875d7;
   color: #fff;
   color: #fff;
 }
 }
-.select2-container .select2-results li em {
+.select2-results li em {
   background: #feffde;
   background: #feffde;
   font-style: normal;
   font-style: normal;
 }
 }
-.select2-container .select2-results .select2-highlighted em {
+.select2-results .select2-highlighted em {
   background: transparent;
   background: transparent;
 }
 }
-.select2-container .select2-results .select2-no-results {
+.select2-results .select2-no-results {
   background: #f4f4f4;
   background: #f4f4f4;
   display: list-item;
   display: list-item;
 }
 }
 
 
 /*
 /*
 disabled look for already selected choices in the results dropdown
 disabled look for already selected choices in the results dropdown
-.select2-container .select2-results .select2-disabled.select2-highlighted {
+.select2-results .select2-disabled.select2-highlighted {
     color: #666;
     color: #666;
     background: #f4f4f4;
     background: #f4f4f4;
     display: list-item;
     display: list-item;
     cursor: default;
     cursor: default;
 }
 }
-.select2-container .select2-results .select2-disabled {
+.select2-results .select2-disabled {
   background: #f4f4f4;
   background: #f4f4f4;
   display: list-item;
   display: list-item;
   cursor: default;
   cursor: default;
 }
 }
 */
 */
-.select2-container .select2-results .select2-disabled {
+.select2-results .select2-disabled {
     display: none;
     display: none;
 }
 }
 
 

+ 47 - 13
select2.js

@@ -1,6 +1,6 @@
 /*
 /*
  Copyright 2012 Igor Vaynberg
  Copyright 2012 Igor Vaynberg
- 
+
  Version: @@ver@@ Timestamp: @@timestamp@@
  Version: @@ver@@ Timestamp: @@timestamp@@
 
 
  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in
  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in
@@ -319,9 +319,16 @@
     $(document).ready(function () {
     $(document).ready(function () {
         $(document).delegate("*", "mousedown focusin touchend", function (e) {
         $(document).delegate("*", "mousedown focusin touchend", function (e) {
             var target = $(e.target).closest("div.select2-container").get(0);
             var target = $(e.target).closest("div.select2-container").get(0);
-            $(document).find("div.select2-container-active").each(function () {
-                if (this !== target) $(this).data("select2").blur();
-            });
+            if (target) {
+                $(document).find("div.select2-container-active").each(function () {
+                    if (this !== target) $(this).data("select2").blur();
+                });
+            } else {
+                target = $(e.target).closest("div.select2-drop").get(0);
+                $(document).find("div.select2-drop-active").each(function () {
+                    if (this !== target) $(this).data("select2").blur();
+                });
+            }
         });
         });
     });
     });
 
 
@@ -378,8 +385,11 @@
             this.container.data("select2", this);
             this.container.data("select2", this);
 
 
             this.dropdown = this.container.find(".select2-drop");
             this.dropdown = this.container.find(".select2-drop");
+            this.dropdown.data("select2", this);
+
             this.results = results = this.container.find(resultsSelector);
             this.results = results = this.container.find(resultsSelector);
             this.search = search = this.container.find("input[type=text]");
             this.search = search = this.container.find("input[type=text]");
+            this.dropdown.detach().appendTo('body');
 
 
             this.resultsPage = 0;
             this.resultsPage = 0;
             this.context = null;
             this.context = null;
@@ -388,10 +398,10 @@
             this.initContainer();
             this.initContainer();
 
 
             installFilteredMouseMove(this.results);
             installFilteredMouseMove(this.results);
-            this.container.delegate(resultsSelector, "mousemove-filtered", this.bind(this.highlightUnderEvent));
+            this.dropdown.delegate(resultsSelector, "mousemove-filtered", this.bind(this.highlightUnderEvent));
 
 
             installDebouncedScroll(80, this.results);
             installDebouncedScroll(80, this.results);
-            this.container.delegate(resultsSelector, "scroll-debounced", this.bind(this.loadMoreIfNeeded));
+            this.dropdown.delegate(resultsSelector, "scroll-debounced", this.bind(this.loadMoreIfNeeded));
 
 
             // if jquery.mousewheel plugin is installed we can prevent out-of-bounds scrolling of results via mousewheel
             // if jquery.mousewheel plugin is installed we can prevent out-of-bounds scrolling of results via mousewheel
             if ($.fn.mousewheel) {
             if ($.fn.mousewheel) {
@@ -412,7 +422,7 @@
             search.bind("focus", function () { search.addClass("select2-focused");});
             search.bind("focus", function () { search.addClass("select2-focused");});
             search.bind("blur", function () { search.removeClass("select2-focused");});
             search.bind("blur", function () { search.removeClass("select2-focused");});
 
 
-            this.container.delegate(resultsSelector, "click", this.bind(function (e) {
+            this.dropdown.delegate(resultsSelector, "click", this.bind(function (e) {
                 if ($(e.target).closest(".select2-result:not(.select2-disabled)").length > 0) {
                 if ($(e.target).closest(".select2-result:not(.select2-disabled)").length > 0) {
                     this.highlightUnderEvent(e);
                     this.highlightUnderEvent(e);
                     this.selectHighlighted(e);
                     this.selectHighlighted(e);
@@ -438,6 +448,7 @@
             var select2 = this.opts.element.data("select2");
             var select2 = this.opts.element.data("select2");
             if (select2 !== undefined) {
             if (select2 !== undefined) {
                 select2.container.remove();
                 select2.container.remove();
+                select2.dropdown.remove();
                 select2.opts.element
                 select2.opts.element
                     .removeData("select2")
                     .removeData("select2")
                     .unbind(".select2")
                     .unbind(".select2")
@@ -568,10 +579,26 @@
             return this.container.hasClass("select2-dropdown-open");
             return this.container.hasClass("select2-dropdown-open");
         },
         },
 
 
+        updatePositions: function() {
+            var offset = this.container.offset();
+            var height = this.container.outerHeight();
+            var width  = this.container.outerWidth();
+
+            this.dropdown.css({
+                top: offset.top + height,
+                left: offset.left,
+                width: width,
+                'max-height': 300
+            });
+        },
+
         open: function () {
         open: function () {
             if (this.opened()) return;
             if (this.opened()) return;
 
 
             this.container.addClass("select2-dropdown-open").addClass("select2-container-active");
             this.container.addClass("select2-dropdown-open").addClass("select2-container-active");
+            this.dropdown.addClass("select2-drop-active");
+
+            this.updatePositions();
 
 
             this.updateResults(true);
             this.updateResults(true);
             this.dropdown.show();
             this.dropdown.show();
@@ -787,6 +814,7 @@
             window.setTimeout(this.bind(function () {
             window.setTimeout(this.bind(function () {
                 this.close();
                 this.close();
                 this.container.removeClass("select2-container-active");
                 this.container.removeClass("select2-container-active");
+                this.dropdown.removeClass("select2-drop-active");
                 this.clearSearch();
                 this.clearSearch();
                 this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");
                 this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");
                 this.search.blur();
                 this.search.blur();
@@ -888,7 +916,11 @@
 
 
         initContainer: function () {
         initContainer: function () {
 
 
-            var selection, container = this.container, clickingInside = false,
+            var selection,
+                container = this.container,
+                dropdown = this.dropdown,
+                containerGroup = $([this.container.get(0), this.dropdown.get(0)]),
+                clickingInside = false,
                 selector = ".select2-choice";
                 selector = ".select2-choice";
 
 
             this.selection = selection = container.find(selector);
             this.selection = selection = container.find(selector);
@@ -912,7 +944,7 @@
                 }
                 }
             }));
             }));
 
 
-            container.delegate(selector, "click", this.bind(function (e) {
+            containerGroup.delegate(selector, "click", this.bind(function (e) {
                 clickingInside = true;
                 clickingInside = true;
 
 
                 if (this.opened()) {
                 if (this.opened()) {
@@ -925,7 +957,7 @@
 
 
                 clickingInside = false;
                 clickingInside = false;
             }));
             }));
-            container.delegate(selector, "keydown", this.bind(function (e) {
+            containerGroup.delegate(selector, "keydown", this.bind(function (e) {
                 if (!this.enabled || e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) {
                 if (!this.enabled || e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) {
                     return;
                     return;
                 }
                 }
@@ -939,8 +971,8 @@
                     killEvent(e);
                     killEvent(e);
                 }
                 }
             }));
             }));
-            container.delegate(selector, "focus", function () { if (this.enabled) container.addClass("select2-container-active"); });
-            container.delegate(selector, "blur", this.bind(function () {
+            containerGroup.delegate(selector, "focus", function () { if (this.enabled) { containerGroup.addClass("select2-container-active"); dropdown.addClass("select2-drop-active"); }});
+            containerGroup.delegate(selector, "blur", this.bind(function () {
                 if (clickingInside) return;
                 if (clickingInside) return;
                 if (!this.opened()) this.blur();
                 if (!this.opened()) this.blur();
             }));
             }));
@@ -1206,6 +1238,7 @@
             this.container.delegate(selector, "focus", this.bind(function () {
             this.container.delegate(selector, "focus", this.bind(function () {
                 if (!this.enabled) return;
                 if (!this.enabled) return;
                 this.container.addClass("select2-container-active");
                 this.container.addClass("select2-container-active");
+                this.dropdown.addClass("select2-drop-active");
                 this.clearPlaceholder();
                 this.clearPlaceholder();
             }));
             }));
 
 
@@ -1357,6 +1390,7 @@
             })).bind("focus", this.bind(function () {
             })).bind("focus", this.bind(function () {
                 if (!this.enabled) return;
                 if (!this.enabled) return;
                 this.container.addClass("select2-container-active");
                 this.container.addClass("select2-container-active");
+                this.dropdown.addClass("select2-drop-active");
             }));
             }));
 
 
             choice.data("select2-data", data);
             choice.data("select2-data", data);
@@ -1522,7 +1556,7 @@
         var args = Array.prototype.slice.call(arguments, 0),
         var args = Array.prototype.slice.call(arguments, 0),
             opts,
             opts,
             select2,
             select2,
-            value, multiple, allowedMethods = ["val", "destroy", "open", "close", "focus", "isFocused", "container", "onSortStart", "onSortEnd", "enable", "disable"];
+            value, multiple, allowedMethods = ["val", "destroy", "open", "close", "focus", "isFocused", "container", "onSortStart", "onSortEnd", "enable", "disable", "updatePositions"];
 
 
         this.each(function () {
         this.each(function () {
             if (args.length === 0 || typeof(args[0]) === "object") {
             if (args.length === 0 || typeof(args[0]) === "object") {