Browse Source

Merge pull request #5 from justindujardin/jdd-sizable

Add support for flexible width select2 elements.
Igor Vaynberg 13 years ago
parent
commit
6fee67bcff
2 changed files with 92 additions and 42 deletions
  1. 61 26
      select2.css
  2. 31 16
      select2.js

+ 61 - 26
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 {
 .select2-container .select2-choice {
     background-color: #fff;
     background-color: #fff;
     background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.5, white));
     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: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 50%);
     background-image: -moz-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%);
     background-image: -ms-linear-gradient(top, #eeeeee 0%, #ffffff 50%);
     filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#eeeeee', endColorstr = '#ffffff', GradientType = 0);
     filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#eeeeee', endColorstr = '#ffffff', GradientType = 0);
     background-image: linear-gradient(top, #eeeeee 0%, #ffffff 50%);
     background-image: linear-gradient(top, #eeeeee 0%, #ffffff 50%);
@@ -69,19 +86,17 @@
     border-top: 0;
     border-top: 0;
     position: absolute;
     position: absolute;
     top: 29px;
     top: 29px;
-    left: 0;
     -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
     -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
     -moz-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);
     -o-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
     box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
     box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
     z-index: 999;
     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;
+  -webkit-border-radius: 0 0 4px 4px;
+  -moz-border-radius: 0 0 4px 4px;
+  border-radius: 0 0 4px 4px;
 }
 }
 
 
 .select2-container .select2-choice div {
 .select2-container .select2-choice div {
@@ -116,11 +131,14 @@
 }
 }
 
 
 .select2-container .select2-search {
 .select2-container .select2-search {
-    padding: 3px 4px;
-    position: relative;
-    margin: 0;
+  display: inline-block;
     white-space: nowrap;
     white-space: nowrap;
     z-index: 1010;
     z-index: 1010;
+  min-height: 26px;
+  width: 100%;
+  margin: 0;
+  padding-left: 4px;
+  padding-right: 4px;
 }
 }
 
 
 .select2-container .select2-search input {
 .select2-container .select2-search input {
@@ -131,12 +149,21 @@
     background: url('select2.png') no-repeat 100% -22px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
     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, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%);
     background: url('select2.png') no-repeat 100% -22px, 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;
     padding: 4px 20px 4px 5px;
     outline: 0;
     outline: 0;
     border: 1px solid #aaa;
     border: 1px solid #aaa;
     font-family: sans-serif;
     font-family: sans-serif;
     font-size: 1em;
     font-size: 1em;
+    width:100%;
+    margin:0;
+    height:auto !important;
+    min-height: 26px;
+    -webkit-box-shadow: none;
+    -moz-box-shadow: none;
+    box-shadow: none;
+    border-radius: 0;
+    -moz-border-radius: 0;
+    -webkit-border-radius: 0;  
 }
 }
 
 
 .select2-container .select2-search input.select2-active {
 .select2-container .select2-search input.select2-active {
@@ -147,28 +174,22 @@
     background: url('spinner.gif') no-repeat 100%, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
     background: url('spinner.gif') no-repeat 100%, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
     background: url('spinner.gif') no-repeat 100%, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%);
     background: url('spinner.gif') no-repeat 100%, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%);
     background: url('spinner.gif') no-repeat 100%, linear-gradient(top, #ffffff 85%, #eeeeee 99%);
     background: url('spinner.gif') no-repeat 100%, 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;
 }
 }
 
 
 
 
 .select2-container-active .select2-choice,
 .select2-container-active .select2-choice,
 .select2-container-active .select2-choices {
 .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 {
 .select2-dropdown-open .select2-choice {
   border: 1px solid #aaa;
   border: 1px solid #aaa;
+  border-bottom: none;
   -webkit-box-shadow: 0 1px 0 #fff inset;
   -webkit-box-shadow: 0 1px 0 #fff inset;
   -moz-box-shadow   : 0 1px 0 #fff inset;
   -moz-box-shadow   : 0 1px 0 #fff inset;
   -o-box-shadow     : 0 1px 0 #fff inset;
   -o-box-shadow     : 0 1px 0 #fff inset;
@@ -199,7 +220,7 @@
 
 
 /* results */
 /* results */
 .select2-container .select2-results {
 .select2-container .select2-results {
-  margin: 0 4px 4px 0;
+  margin: 4px 4px 4px 0;
   padding: 0 0 0 4px;
   padding: 0 0 0 4px;
   position: relative;
   position: relative;
   overflow-x: hidden;
   overflow-x: hidden;
@@ -272,6 +293,19 @@
       height: 1%;
       height: 1%;
       position: relative;
       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 {
 .select2-container-multi .select2-choices li {
   float: left;
   float: left;
   list-style: none;
   list-style: none;
@@ -345,6 +379,7 @@
   height: 13px;
   height: 13px;
   font-size: 1px;
   font-size: 1px;
   background: url(select2.png) right top no-repeat;
   background: url(select2.png) right top no-repeat;
+  outline: none;
 }
 }
 
 
 .select2-container-multi .select2-search-choice-close {
 .select2-container-multi .select2-search-choice-close {

+ 31 - 16
select2.js

@@ -1,4 +1,4 @@
-/*
+/*
  Licensed to the Apache Software Foundation (ASF) under one
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  distributed with this work for additional information
@@ -390,14 +390,11 @@
 
 
     AbstractSelect2.prototype.alignDropdown = function () {
     AbstractSelect2.prototype.alignDropdown = function () {
         this.dropdown.css({
         this.dropdown.css({
-            top: this.container.height(),
-            width: this.container.outerWidth() - getSideBorderPadding(this.dropdown)
+            top: this.container.height()
         });
         });
     };
     };
 
 
     AbstractSelect2.prototype.open = function () {
     AbstractSelect2.prototype.open = function () {
-        var width;
-
         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");
@@ -614,6 +611,32 @@
         return this.opts.placeholder;
         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');
+        if(style !== undefined){
+            var attrs = style.split(';');
+            for (var i = 0; i < attrs.length; i++) {
+                var matches = attrs[i].replace(/\s/g,'')
+                .match(/width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/);
+                if(matches != null && matches.length >= 1)
+                    return matches[1];
+            }
+        }
+        return this.opts.element.width() + 'px';
+    };
+    
+
     function SingleSelect2() {
     function SingleSelect2() {
     }
     }
 
 
@@ -624,7 +647,7 @@
     SingleSelect2.prototype.createContainer = function () {
     SingleSelect2.prototype.createContainer = function () {
         return $("<div></div>", {
         return $("<div></div>", {
             "class": "select2-container",
             "class": "select2-container",
-            "style": "width: " + this.opts.element.outerWidth() + "px"
+            "style": "width: " + this.getContainerWidth()
         }).html([
         }).html([
             "    <a href='javascript:void(0)' class='select2-choice'>",
             "    <a href='javascript:void(0)' class='select2-choice'>",
             "   <span></span><abbr class='select2-search-choice-close' style='display:none;'></abbr>",
             "   <span></span><abbr class='select2-search-choice-close' style='display:none;'></abbr>",
@@ -641,18 +664,10 @@
 
 
     SingleSelect2.prototype.open = function () {
     SingleSelect2.prototype.open = function () {
 
 
-        var width;
-
         if (this.opened()) return;
         if (this.opened()) return;
 
 
         this.parent.open.apply(this, arguments);
         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 () {
     SingleSelect2.prototype.close = function () {
@@ -777,7 +792,7 @@
         // hide the search box if this is the first we got the results and there are a few of them
         // hide the search box if this is the first we got the results and there are a few of them
 
 
         if (initial === true) {
         if (initial === true) {
-            this.search.toggle(data.results.length >= this.opts.minimumResultsForSearch);
+            this.search.parent().toggle(data.results.length >= this.opts.minimumResultsForSearch);
         }
         }
 
 
     };
     };
@@ -847,7 +862,7 @@
     MultiSelect2.prototype.createContainer = function () {
     MultiSelect2.prototype.createContainer = function () {
         return $("<div></div>", {
         return $("<div></div>", {
             "class": "select2-container select2-container-multi",
             "class": "select2-container select2-container-multi",
-            "style": "width: " + this.opts.element.outerWidth() + "px"
+            "style": "width: " + this.getContainerWidth()
         }).html([
         }).html([
             "    <ul class='select2-choices'>",
             "    <ul class='select2-choices'>",
             //"<li class='select2-search-choice'><span>California</span><a href="javascript:void(0)" class="select2-search-choice-close"></a></li>" ,
             //"<li class='select2-search-choice'><span>California</span><a href="javascript:void(0)" class="select2-search-choice-close"></a></li>" ,