소스 검색

Rework select2 and styles to support styled width's (rather than just fixed pixel widths)
- Will not work with styles specified in remote CSS, because there's no easy way to retrieve the original css value.
- Will work with styles specified inline on the element (regex parse out width value with specified units intact, from the element style attribute)

Tested in Firefox,Chrome,Safari,Opera

Justin DuJardin 13 년 전
부모
커밋
b2c6ced65f
2개의 변경된 파일108개의 추가작업 그리고 64개의 파일을 삭제
  1. 45 16
      select2.css
  2. 63 48
      select2.js

+ 45 - 16
select2.css

@@ -7,12 +7,29 @@
 
 }
 
+.select2-container,
+.select2-drop,
+.select2-search,
+.select2-container .select2-search input{
+  /* 
+    Force border-box so that % widths fit the parent
+    container without overlap because of margin/padding.
+    
+    More Info : http://www.quirksmode.org/css/box.html
+  */
+  -moz-box-sizing: border-box;    /* firefox */
+  -ms-box-sizing: border-box;     /* ie */
+  -webkit-box-sizing: border-box; /* webkit */
+  -khtml-box-sizing: border-box;  /* konqueror */
+  box-sizing: border-box;         /* css3 */
+}
+
 .select2-container .select2-choice {
     background-color: #fff;
     background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.5, white));
     background-image: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 50%);
     background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 50%);
-    background-image: -o-linear-gradient(top, #eeeeee 0%, #ffffff 50%);
+    background-image: -o-linear-gradient(bottom, #eeeeee 0%, #ffffff 50%);
     background-image: -ms-linear-gradient(top, #eeeeee 0%, #ffffff 50%);
     filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#eeeeee', endColorstr = '#ffffff', GradientType = 0);
     background-image: linear-gradient(top, #eeeeee 0%, #ffffff 50%);
@@ -69,19 +86,17 @@
     border-top: 0;
     position: absolute;
     top: 29px;
-    left: 0;
     -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
     -moz-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
     -o-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
     box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
     z-index: 999;
+    width:100%;
+    margin-top:-1px;
 
     -webkit-border-radius: 0 0 4px 4px;
     -moz-border-radius: 0 0 4px 4px;
     border-radius: 0 0 4px 4px;
-    -moz-background-clip: padding;
-    -webkit-background-clip: padding-box;
-    background-clip: padding-box;
 }
 
 .select2-container .select2-choice div {
@@ -116,11 +131,12 @@
 }
 
 .select2-container .select2-search {
-    padding: 3px 4px;
-    position: relative;
     margin: 0;
     white-space: nowrap;
     z-index: 1010;
+    position: absolute;
+    left:4px;
+    right:4px;    
 }
 
 .select2-container .select2-search input {
@@ -131,12 +147,12 @@
     background: url('select2.png') no-repeat 100% -22px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
     background: url('select2.png') no-repeat 100% -22px, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%);
     background: url('select2.png') no-repeat 100% -22px, linear-gradient(top, #ffffff 85%, #eeeeee 99%);
-    margin: 1px 0;
     padding: 4px 20px 4px 5px;
     outline: 0;
     border: 1px solid #aaa;
     font-family: sans-serif;
     font-size: 1em;
+    width:100%;    
 }
 
 .select2-container .select2-search input.select2-active {
@@ -158,17 +174,17 @@
 
 .select2-container-active .select2-choice,
 .select2-container-active .select2-choices {
-    -webkit-box-shadow: none;
-    -moz-box-shadow: none;
-    box-shadow: none;
-    outline: thin dotted #333;
-    outline: 5px auto -webkit-focus-ring-color;
-    outline-offset: -2px;
-
+    -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3);
+    -moz-box-shadow   : 0 0 5px rgba(0,0,0,.3);
+    -o-box-shadow     : 0 0 5px rgba(0,0,0,.3);
+    box-shadow        : 0 0 5px rgba(0,0,0,.3);
+    border: 1px solid #5897fb;
+    outline: none;
 }
 
 .select2-dropdown-open .select2-choice {
   border: 1px solid #aaa;
+  border-bottom: none;
   -webkit-box-shadow: 0 1px 0 #fff inset;
   -moz-box-shadow   : 0 1px 0 #fff inset;
   -o-box-shadow     : 0 1px 0 #fff inset;
@@ -199,7 +215,7 @@
 
 /* results */
 .select2-container .select2-results {
-  margin: 0 4px 4px 0;
+  margin: 30px 4px 4px 0;
   padding: 0 0 0 4px;
   position: relative;
   overflow-x: hidden;
@@ -272,6 +288,19 @@
       height: 1%;
       position: relative;
 }
+
+.select2-container-multi .select2-drop {
+    margin-top:0;
+}
+
+.select2-container-multi.select2-container-active .select2-choices {
+    -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3);
+    -moz-box-shadow   : 0 0 5px rgba(0,0,0,.3);
+    -o-box-shadow     : 0 0 5px rgba(0,0,0,.3);
+    box-shadow        : 0 0 5px rgba(0,0,0,.3);
+    border: 1px solid #5897fb;
+    outline: none;
+}
 .select2-container-multi .select2-choices li {
   float: left;
   list-style: none;

+ 63 - 48
select2.js

@@ -301,36 +301,36 @@
         } else {
             if (!("query" in opts)) {
                 if ("ajax" in opts) {
-                    opts.query = (function () {
-                        var timeout, // current scheduled but not yet executed request
-                            requestSequence = 0, // sequence used to drop out-of-order responses
-                            quietMillis = opts.ajax.quietMillis || 100;
-
-                        return function (query) {
-                            window.clearTimeout(timeout);
-                            timeout = window.setTimeout(function () {
-                                requestSequence += 1; // increment the sequence
-                                var requestNumber = requestSequence, // this request's sequence number
-                                    options = opts.ajax, // ajax parameters
-                                    data = options.data; // ajax data function
-
-                                data = data.call(this, query.term, query.page);
-
-                                $.ajax({
-                                    url: options.url,
-                                    dataType: options.dataType,
-                                    data: data
-                                }).success(
-                                    function (data) {
-                                        if (requestNumber < requestSequence) {
-                                            return;
-                                        }
-                                        query.callback(options.results(data, query.page));
+                opts.query = (function () {
+                    var timeout, // current scheduled but not yet executed request
+                        requestSequence = 0, // sequence used to drop out-of-order responses
+                        quietMillis = opts.ajax.quietMillis || 100;
+
+                    return function (query) {
+                        window.clearTimeout(timeout);
+                        timeout = window.setTimeout(function () {
+                            requestSequence += 1; // increment the sequence
+                            var requestNumber = requestSequence, // this request's sequence number
+                                options = opts.ajax, // ajax parameters
+                                data = options.data; // ajax data function
+
+                            data = data.call(this, query.term, query.page);
+
+                            $.ajax({
+                                url: options.url,
+                                dataType: options.dataType,
+                                data: data
+                            }).success(
+                                function (data) {
+                                    if (requestNumber < requestSequence) {
+                                        return;
                                     }
-                                );
-                            }, quietMillis);
-                        };
-                    }());
+                                    query.callback(options.results(data, query.page));
+                                }
+                            );
+                        }, quietMillis);
+                    };
+                }());
                 } else if ("data" in opts) {
                     opts.query = (function () {
                         var data = opts.data, // data elements
@@ -355,9 +355,9 @@
                             query.callback(filtered);
                         };
                     }());
-                }
             }
         }
+        }
         if (typeof(opts.query) !== "function") {
             throw "query function not defined for Select2 " + opts.element.attr("id");
         }
@@ -371,14 +371,11 @@
 
     AbstractSelect2.prototype.alignDropdown = function () {
         this.dropdown.css({
-            top: this.container.height(),
-            width: this.container.outerWidth() - getSideBorderPadding(this.dropdown)
+            top: this.container.height()
         });
     };
 
     AbstractSelect2.prototype.open = function () {
-        var width;
-
         if (this.opened()) return;
 
         this.container.addClass("select2-dropdown-open").addClass("select2-container-active");
@@ -394,7 +391,7 @@
 
         this.dropdown.hide();
         this.container.removeClass("select2-dropdown-open");
-        this.results.empty();
+            this.results.empty();
         this.clearSearch();
     };
 
@@ -595,6 +592,32 @@
         return this.opts.placeholder;
     };
 
+    /**
+     * Get the desired width for the container element.  This is
+     * derived first from option `width` passed to select2, then
+     * the inline 'style' on the original element, and finally
+     * falls back to the jQuery calculated element width.
+     *
+     * @returns The width string (with units) for the container.
+     */
+    AbstractSelect2.prototype.getContainerWidth = function() {
+        if (this.opts.width !== undefined)
+            return this.opts.width;
+        
+        var style = this.opts.element.attr('style');
+        var attrs = style.split(';');
+        for (var i = 0; i < attrs.length; i++) {
+            var attr = attrs[i].trim();
+            var matches = attr.match(/width:(([0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/);
+            if(matches == null || matches.length < 1)
+                continue;
+            return matches[1];
+        }
+
+        return this.opts.element.width();
+    }
+    
+
     function SingleSelect2() {
     }
 
@@ -605,7 +628,7 @@
     SingleSelect2.prototype.createContainer = function () {
         return $("<div></div>", {
             "class": "select2-container",
-            "style": "width: " + this.opts.element.outerWidth() + "px"
+            "style": "width: " + this.getContainerWidth()
         }).html([
             "    <a href='javascript:void(0)' class='select2-choice'>",
             "   <span></span><abbr class='select2-search-choice-close' style='display:none;'></abbr>",
@@ -622,18 +645,10 @@
 
     SingleSelect2.prototype.open = function () {
 
-        var width;
-
         if (this.opened()) return;
 
         this.parent.open.apply(this, arguments);
 
-        // size the search field
-
-        width = this.dropdown.width();
-        width -= getSideBorderPadding(this.container.find(".select2-search"));
-        width -= getSideBorderPadding(this.search);
-        this.search.css({width: width});
     };
 
     SingleSelect2.prototype.close = function () {
@@ -795,9 +810,9 @@
             this.select
                 .val(val)
                 .find(":selected").each(function () {
-                    data = {id: $(this).attr("value"), text: $(this).text()};
-                    return false;
-                });
+                data = {id: $(this).attr("value"), text: $(this).text()};
+                return false;
+            });
             this.updateSelection(data);
         } else {
             // val is an object
@@ -823,7 +838,7 @@
     MultiSelect2.prototype.createContainer = function () {
         return $("<div></div>", {
             "class": "select2-container select2-container-multi",
-            "style": "width: " + this.opts.element.outerWidth() + "px"
+            "style": "width: " + this.getContainerWidth()
         }).html([
             "    <ul class='select2-choices'>",
             //"<li class='select2-search-choice'><span>California</span><a href="javascript:void(0)" class="select2-search-choice-close"></a></li>" ,