1
0
mirror of synced 2024-12-01 09:06:03 +03:00

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
This commit is contained in:
Justin DuJardin 2012-03-27 16:04:35 -07:00
parent eddc40934c
commit b2c6ced65f
2 changed files with 105 additions and 61 deletions

View File

@ -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; -webkit-border-radius: 0 0 4px 4px;
-moz-border-radius: 0 0 4px 4px; -moz-border-radius: 0 0 4px 4px;
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 { .select2-container .select2-choice div {
@ -116,11 +131,12 @@
} }
.select2-container .select2-search { .select2-container .select2-search {
padding: 3px 4px;
position: relative;
margin: 0; margin: 0;
white-space: nowrap; white-space: nowrap;
z-index: 1010; z-index: 1010;
position: absolute;
left:4px;
right:4px;
} }
.select2-container .select2-search input { .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, -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%;
} }
.select2-container .select2-search input.select2-active { .select2-container .select2-search input.select2-active {
@ -158,17 +174,17 @@
.select2-container-active .select2-choice, .select2-container-active .select2-choice,
.select2-container-active .select2-choices { .select2-container-active .select2-choices {
-webkit-box-shadow: none; -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3);
-moz-box-shadow: none; -moz-box-shadow : 0 0 5px rgba(0,0,0,.3);
box-shadow: none; -o-box-shadow : 0 0 5px rgba(0,0,0,.3);
outline: thin dotted #333; box-shadow : 0 0 5px rgba(0,0,0,.3);
outline: 5px auto -webkit-focus-ring-color; border: 1px solid #5897fb;
outline-offset: -2px; 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 +215,7 @@
/* results */ /* results */
.select2-container .select2-results { .select2-container .select2-results {
margin: 0 4px 4px 0; margin: 30px 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 +288,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;

View File

@ -301,36 +301,36 @@
} else { } else {
if (!("query" in opts)) { if (!("query" in opts)) {
if ("ajax" in opts) { if ("ajax" in opts) {
opts.query = (function () { opts.query = (function () {
var timeout, // current scheduled but not yet executed request var timeout, // current scheduled but not yet executed request
requestSequence = 0, // sequence used to drop out-of-order responses requestSequence = 0, // sequence used to drop out-of-order responses
quietMillis = opts.ajax.quietMillis || 100; quietMillis = opts.ajax.quietMillis || 100;
return function (query) { return function (query) {
window.clearTimeout(timeout); window.clearTimeout(timeout);
timeout = window.setTimeout(function () { timeout = window.setTimeout(function () {
requestSequence += 1; // increment the sequence requestSequence += 1; // increment the sequence
var requestNumber = requestSequence, // this request's sequence number var requestNumber = requestSequence, // this request's sequence number
options = opts.ajax, // ajax parameters options = opts.ajax, // ajax parameters
data = options.data; // ajax data function data = options.data; // ajax data function
data = data.call(this, query.term, query.page); data = data.call(this, query.term, query.page);
$.ajax({ $.ajax({
url: options.url, url: options.url,
dataType: options.dataType, dataType: options.dataType,
data: data data: data
}).success( }).success(
function (data) { function (data) {
if (requestNumber < requestSequence) { if (requestNumber < requestSequence) {
return; return;
}
query.callback(options.results(data, query.page));
} }
); query.callback(options.results(data, query.page));
}, quietMillis); }
}; );
}()); }, quietMillis);
};
}());
} else if ("data" in opts) { } else if ("data" in opts) {
opts.query = (function () { opts.query = (function () {
var data = opts.data, // data elements var data = opts.data, // data elements
@ -355,9 +355,9 @@
query.callback(filtered); query.callback(filtered);
}; };
}()); }());
}
} }
} }
}
if (typeof(opts.query) !== "function") { if (typeof(opts.query) !== "function") {
throw "query function not defined for Select2 " + opts.element.attr("id"); throw "query function not defined for Select2 " + opts.element.attr("id");
} }
@ -371,14 +371,11 @@
AbstractSelect2.prototype.alignDropdown = function () { AbstractSelect2.prototype.alignDropdown = function () {
this.dropdown.css({ this.dropdown.css({
top: this.container.height(), top: this.container.height()
width: this.container.outerWidth() - getSideBorderPadding(this.dropdown)
}); });
}; };
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");
@ -394,7 +391,7 @@
this.dropdown.hide(); this.dropdown.hide();
this.container.removeClass("select2-dropdown-open"); this.container.removeClass("select2-dropdown-open");
this.results.empty(); this.results.empty();
this.clearSearch(); this.clearSearch();
}; };
@ -595,6 +592,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');
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() { function SingleSelect2() {
} }
@ -605,7 +628,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>",
@ -622,18 +645,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 () {
@ -795,9 +810,9 @@
this.select this.select
.val(val) .val(val)
.find(":selected").each(function () { .find(":selected").each(function () {
data = {id: $(this).attr("value"), text: $(this).text()}; data = {id: $(this).attr("value"), text: $(this).text()};
return false; return false;
}); });
this.updateSelection(data); this.updateSelection(data);
} else { } else {
// val is an object // val is an object
@ -823,7 +838,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>" ,