1
0
mirror of synced 2024-11-22 13:06:08 +03:00

Respect the disabled attribute

Added a disabled state for Select2. This will correctly listen to
property changes (so when the disabled property is changed) and
update the state of Select2 to reflect it.

Added a utility function to find a method to a different context.
This commit is contained in:
Kevin Brown 2014-12-16 22:44:11 -05:00
parent 1e44ab7ee1
commit 358306ac8c
18 changed files with 567 additions and 17 deletions

View File

@ -134,6 +134,9 @@
position: absolute;
top: 50%;
width: 0; }
.select2-container--default.select2-container--disabled .select2-selection--single {
background-color: #eee;
cursor: default; }
.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
border-color: transparent transparent #888 transparent;
border-width: 0 4px 5px 4px; }
@ -167,6 +170,9 @@
margin-right: 2px; }
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
color: #333; }
.select2-container--default.select2-container--disabled .select2-selection--multiple {
background-color: #eee;
cursor: default; }
.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple {
border-top-left-radius: 0;
border-top-right-radius: 0; }
@ -176,6 +182,7 @@
.select2-container--default .select2-search--dropdown .select2-search__field {
border: 1px solid #aaa; }
.select2-container--default .select2-search--inline .select2-search__field {
background: transparent;
border: none;
outline: 0; }
.select2-container--default .select2-results > .select2-results__options {

File diff suppressed because one or more lines are too long

View File

@ -153,6 +153,12 @@ window.$ = window.$ || {};(function() { if ($ && $.fn && $.fn.select2 && $.fn.se
return chars;
};
Utils.bind = function (func, context) {
return function () {
func.apply(context, arguments);
};
};
return Utils;
});
@ -813,6 +819,14 @@ define('select2/selection/single',[
// User exits the container
});
container.on('enable', function () {
self.$selection.attr('tabindex', '0');
});
container.on('disable', function () {
self.$selection.attr('tabindex', '-1');
});
container.on('selection:update', function (params) {
self.update(params.data);
});
@ -897,6 +911,14 @@ define('select2/selection/multiple',[
data: data
});
});
container.on('enable', function () {
self.$selection.attr('tabindex', '0');
});
container.on('disable', function () {
self.$selection.attr('tabindex', '-1');
});
};
MultipleSelection.prototype.clear = function () {
@ -1078,6 +1100,14 @@ define('select2/selection/search',[
self.$search.val('');
});
container.on('enable', function () {
self.$search.prop('disabled', false);
});
container.on('disable', function () {
self.$search.prop('disabled', true);
});
this.$selection.on('keydown', '.select2-search--inline', function (evt) {
evt.stopPropagation();
@ -3379,6 +3409,10 @@ define('select2/options',[
this.options.multiple = $e.prop('multiple');
}
if (this.options.disabled == null) {
this.options.disabled = $e.prop('disabled');
}
if (this.options.language == null) {
if ($e.prop('lang')) {
this.options.language = $e.prop('lang').toLowerCase();
@ -3387,6 +3421,9 @@ define('select2/options',[
}
}
$e.prop('disabled', this.options.disabled);
$e.prop('multiple', this.options.multiple);
var data = $e.data();
function convertData (data) {
@ -3517,7 +3554,6 @@ define('select2/core',[
this._registerEvents();
// Set the initial state
this.data.current(function (initialData) {
self.trigger('selection:update', {
data: initialData
@ -3525,9 +3561,11 @@ define('select2/core',[
});
// Hide the original select
$element.hide();
// Synchronize any monitored attributes
this._syncAttributes();
this._tabindex = $element.attr('tabindex') || 0;
$element.attr('tabindex', '-1');
@ -3576,6 +3614,27 @@ define('select2/core',[
});
});
});
this._sync = Utils.bind(this._syncAttributes, this);
if (this.$element[0].attachEvent) {
this.$element[0].attachEvent('onpropertychange', this._sync);
}
var observer = window.MutationObserver ||
window.WebKitMutationObserver ||
window.MozMutationObserver
;
if (observer != null) {
this._observer = new observer(function (mutations) {
$.each(mutations, self._sync);
});
this._observer.observe(this.$element[0], {
attributes: true,
subtree: false
});
}
};
Select2.prototype._registerDataEvents = function () {
@ -3671,6 +3730,14 @@ define('select2/core',[
self.$container.removeClass('select2-container--open');
});
this.on('enable', function () {
self.$container.removeClass('select2-container--disabled');
});
this.on('disable', function () {
self.$container.addClass('select2-container--disabled');
});
this.on('query', function (params) {
this.data.query(params, function (data) {
self.trigger('results:all', {
@ -3720,7 +3787,25 @@ define('select2/core',[
});
};
Select2.prototype._syncAttributes = function () {
this.options.set('disabled', this.$element.prop('disabled'));
if (this.options.get('disabled')) {
if (this.isOpen()) {
this.trigger('close');
}
this.trigger('disable');
} else {
this.trigger('enable');
}
};
Select2.prototype.toggleDropdown = function () {
if (this.options.get('disabled')) {
return;
}
if (this.isOpen()) {
this.close();
} else {
@ -3794,6 +3879,17 @@ define('select2/core',[
Select2.prototype.destroy = function () {
this.$container.remove();
if (this.$element[0].detachEvent) {
this.$element[0].detachEvent('onpropertychange', this._sync);
}
if (this._observer != null) {
this._observer.disconnect();
this._observer = null;
}
this._sync = null;
this.$element.off('.select2');
this.$element.attr('tabindex', this._tabindex);

100
dist/js/select2.amd.js vendored
View File

@ -153,6 +153,12 @@ window.$ = window.$ || {};(function() { if ($ && $.fn && $.fn.select2 && $.fn.se
return chars;
};
Utils.bind = function (func, context) {
return function () {
func.apply(context, arguments);
};
};
return Utils;
});
@ -813,6 +819,14 @@ define('select2/selection/single',[
// User exits the container
});
container.on('enable', function () {
self.$selection.attr('tabindex', '0');
});
container.on('disable', function () {
self.$selection.attr('tabindex', '-1');
});
container.on('selection:update', function (params) {
self.update(params.data);
});
@ -897,6 +911,14 @@ define('select2/selection/multiple',[
data: data
});
});
container.on('enable', function () {
self.$selection.attr('tabindex', '0');
});
container.on('disable', function () {
self.$selection.attr('tabindex', '-1');
});
};
MultipleSelection.prototype.clear = function () {
@ -1078,6 +1100,14 @@ define('select2/selection/search',[
self.$search.val('');
});
container.on('enable', function () {
self.$search.prop('disabled', false);
});
container.on('disable', function () {
self.$search.prop('disabled', true);
});
this.$selection.on('keydown', '.select2-search--inline', function (evt) {
evt.stopPropagation();
@ -3379,6 +3409,10 @@ define('select2/options',[
this.options.multiple = $e.prop('multiple');
}
if (this.options.disabled == null) {
this.options.disabled = $e.prop('disabled');
}
if (this.options.language == null) {
if ($e.prop('lang')) {
this.options.language = $e.prop('lang').toLowerCase();
@ -3387,6 +3421,9 @@ define('select2/options',[
}
}
$e.prop('disabled', this.options.disabled);
$e.prop('multiple', this.options.multiple);
var data = $e.data();
function convertData (data) {
@ -3517,7 +3554,6 @@ define('select2/core',[
this._registerEvents();
// Set the initial state
this.data.current(function (initialData) {
self.trigger('selection:update', {
data: initialData
@ -3525,9 +3561,11 @@ define('select2/core',[
});
// Hide the original select
$element.hide();
// Synchronize any monitored attributes
this._syncAttributes();
this._tabindex = $element.attr('tabindex') || 0;
$element.attr('tabindex', '-1');
@ -3576,6 +3614,27 @@ define('select2/core',[
});
});
});
this._sync = Utils.bind(this._syncAttributes, this);
if (this.$element[0].attachEvent) {
this.$element[0].attachEvent('onpropertychange', this._sync);
}
var observer = window.MutationObserver ||
window.WebKitMutationObserver ||
window.MozMutationObserver
;
if (observer != null) {
this._observer = new observer(function (mutations) {
$.each(mutations, self._sync);
});
this._observer.observe(this.$element[0], {
attributes: true,
subtree: false
});
}
};
Select2.prototype._registerDataEvents = function () {
@ -3671,6 +3730,14 @@ define('select2/core',[
self.$container.removeClass('select2-container--open');
});
this.on('enable', function () {
self.$container.removeClass('select2-container--disabled');
});
this.on('disable', function () {
self.$container.addClass('select2-container--disabled');
});
this.on('query', function (params) {
this.data.query(params, function (data) {
self.trigger('results:all', {
@ -3720,7 +3787,25 @@ define('select2/core',[
});
};
Select2.prototype._syncAttributes = function () {
this.options.set('disabled', this.$element.prop('disabled'));
if (this.options.get('disabled')) {
if (this.isOpen()) {
this.trigger('close');
}
this.trigger('disable');
} else {
this.trigger('enable');
}
};
Select2.prototype.toggleDropdown = function () {
if (this.options.get('disabled')) {
return;
}
if (this.isOpen()) {
this.close();
} else {
@ -3794,6 +3879,17 @@ define('select2/core',[
Select2.prototype.destroy = function () {
this.$container.remove();
if (this.$element[0].detachEvent) {
this.$element[0].detachEvent('onpropertychange', this._sync);
}
if (this._observer != null) {
this._observer.disconnect();
this._observer = null;
}
this._sync = null;
this.$element.off('.select2');
this.$element.attr('tabindex', this._tabindex);

View File

@ -9688,6 +9688,12 @@ define('select2/utils',[], function () {
return chars;
};
Utils.bind = function (func, context) {
return function () {
func.apply(context, arguments);
};
};
return Utils;
});
@ -10348,6 +10354,14 @@ define('select2/selection/single',[
// User exits the container
});
container.on('enable', function () {
self.$selection.attr('tabindex', '0');
});
container.on('disable', function () {
self.$selection.attr('tabindex', '-1');
});
container.on('selection:update', function (params) {
self.update(params.data);
});
@ -10432,6 +10446,14 @@ define('select2/selection/multiple',[
data: data
});
});
container.on('enable', function () {
self.$selection.attr('tabindex', '0');
});
container.on('disable', function () {
self.$selection.attr('tabindex', '-1');
});
};
MultipleSelection.prototype.clear = function () {
@ -10613,6 +10635,14 @@ define('select2/selection/search',[
self.$search.val('');
});
container.on('enable', function () {
self.$search.prop('disabled', false);
});
container.on('disable', function () {
self.$search.prop('disabled', true);
});
this.$selection.on('keydown', '.select2-search--inline', function (evt) {
evt.stopPropagation();
@ -12914,6 +12944,10 @@ define('select2/options',[
this.options.multiple = $e.prop('multiple');
}
if (this.options.disabled == null) {
this.options.disabled = $e.prop('disabled');
}
if (this.options.language == null) {
if ($e.prop('lang')) {
this.options.language = $e.prop('lang').toLowerCase();
@ -12922,6 +12956,9 @@ define('select2/options',[
}
}
$e.prop('disabled', this.options.disabled);
$e.prop('multiple', this.options.multiple);
var data = $e.data();
function convertData (data) {
@ -13052,7 +13089,6 @@ define('select2/core',[
this._registerEvents();
// Set the initial state
this.data.current(function (initialData) {
self.trigger('selection:update', {
data: initialData
@ -13060,9 +13096,11 @@ define('select2/core',[
});
// Hide the original select
$element.hide();
// Synchronize any monitored attributes
this._syncAttributes();
this._tabindex = $element.attr('tabindex') || 0;
$element.attr('tabindex', '-1');
@ -13111,6 +13149,27 @@ define('select2/core',[
});
});
});
this._sync = Utils.bind(this._syncAttributes, this);
if (this.$element[0].attachEvent) {
this.$element[0].attachEvent('onpropertychange', this._sync);
}
var observer = window.MutationObserver ||
window.WebKitMutationObserver ||
window.MozMutationObserver
;
if (observer != null) {
this._observer = new observer(function (mutations) {
$.each(mutations, self._sync);
});
this._observer.observe(this.$element[0], {
attributes: true,
subtree: false
});
}
};
Select2.prototype._registerDataEvents = function () {
@ -13206,6 +13265,14 @@ define('select2/core',[
self.$container.removeClass('select2-container--open');
});
this.on('enable', function () {
self.$container.removeClass('select2-container--disabled');
});
this.on('disable', function () {
self.$container.addClass('select2-container--disabled');
});
this.on('query', function (params) {
this.data.query(params, function (data) {
self.trigger('results:all', {
@ -13255,7 +13322,25 @@ define('select2/core',[
});
};
Select2.prototype._syncAttributes = function () {
this.options.set('disabled', this.$element.prop('disabled'));
if (this.options.get('disabled')) {
if (this.isOpen()) {
this.trigger('close');
}
this.trigger('disable');
} else {
this.trigger('enable');
}
};
Select2.prototype.toggleDropdown = function () {
if (this.options.get('disabled')) {
return;
}
if (this.isOpen()) {
this.close();
} else {
@ -13329,6 +13414,17 @@ define('select2/core',[
Select2.prototype.destroy = function () {
this.$container.remove();
if (this.$element[0].detachEvent) {
this.$element[0].detachEvent('onpropertychange', this._sync);
}
if (this._observer != null) {
this._observer.disconnect();
this._observer = null;
}
this._sync = null;
this.$element.off('.select2');
this.$element.attr('tabindex', this._tabindex);

File diff suppressed because one or more lines are too long

100
dist/js/select2.js vendored
View File

@ -581,6 +581,12 @@ define('select2/utils',[], function () {
return chars;
};
Utils.bind = function (func, context) {
return function () {
func.apply(context, arguments);
};
};
return Utils;
});
@ -1241,6 +1247,14 @@ define('select2/selection/single',[
// User exits the container
});
container.on('enable', function () {
self.$selection.attr('tabindex', '0');
});
container.on('disable', function () {
self.$selection.attr('tabindex', '-1');
});
container.on('selection:update', function (params) {
self.update(params.data);
});
@ -1325,6 +1339,14 @@ define('select2/selection/multiple',[
data: data
});
});
container.on('enable', function () {
self.$selection.attr('tabindex', '0');
});
container.on('disable', function () {
self.$selection.attr('tabindex', '-1');
});
};
MultipleSelection.prototype.clear = function () {
@ -1506,6 +1528,14 @@ define('select2/selection/search',[
self.$search.val('');
});
container.on('enable', function () {
self.$search.prop('disabled', false);
});
container.on('disable', function () {
self.$search.prop('disabled', true);
});
this.$selection.on('keydown', '.select2-search--inline', function (evt) {
evt.stopPropagation();
@ -3807,6 +3837,10 @@ define('select2/options',[
this.options.multiple = $e.prop('multiple');
}
if (this.options.disabled == null) {
this.options.disabled = $e.prop('disabled');
}
if (this.options.language == null) {
if ($e.prop('lang')) {
this.options.language = $e.prop('lang').toLowerCase();
@ -3815,6 +3849,9 @@ define('select2/options',[
}
}
$e.prop('disabled', this.options.disabled);
$e.prop('multiple', this.options.multiple);
var data = $e.data();
function convertData (data) {
@ -3945,7 +3982,6 @@ define('select2/core',[
this._registerEvents();
// Set the initial state
this.data.current(function (initialData) {
self.trigger('selection:update', {
data: initialData
@ -3953,9 +3989,11 @@ define('select2/core',[
});
// Hide the original select
$element.hide();
// Synchronize any monitored attributes
this._syncAttributes();
this._tabindex = $element.attr('tabindex') || 0;
$element.attr('tabindex', '-1');
@ -4004,6 +4042,27 @@ define('select2/core',[
});
});
});
this._sync = Utils.bind(this._syncAttributes, this);
if (this.$element[0].attachEvent) {
this.$element[0].attachEvent('onpropertychange', this._sync);
}
var observer = window.MutationObserver ||
window.WebKitMutationObserver ||
window.MozMutationObserver
;
if (observer != null) {
this._observer = new observer(function (mutations) {
$.each(mutations, self._sync);
});
this._observer.observe(this.$element[0], {
attributes: true,
subtree: false
});
}
};
Select2.prototype._registerDataEvents = function () {
@ -4099,6 +4158,14 @@ define('select2/core',[
self.$container.removeClass('select2-container--open');
});
this.on('enable', function () {
self.$container.removeClass('select2-container--disabled');
});
this.on('disable', function () {
self.$container.addClass('select2-container--disabled');
});
this.on('query', function (params) {
this.data.query(params, function (data) {
self.trigger('results:all', {
@ -4148,7 +4215,25 @@ define('select2/core',[
});
};
Select2.prototype._syncAttributes = function () {
this.options.set('disabled', this.$element.prop('disabled'));
if (this.options.get('disabled')) {
if (this.isOpen()) {
this.trigger('close');
}
this.trigger('disable');
} else {
this.trigger('enable');
}
};
Select2.prototype.toggleDropdown = function () {
if (this.options.get('disabled')) {
return;
}
if (this.isOpen()) {
this.close();
} else {
@ -4222,6 +4307,17 @@ define('select2/core',[
Select2.prototype.destroy = function () {
this.$container.remove();
if (this.$element[0].detachEvent) {
this.$element[0].detachEvent('onpropertychange', this._sync);
}
if (this._observer != null) {
this._observer.disconnect();
this._observer = null;
}
this._sync = null;
this.$element.off('.select2');
this.$element.attr('tabindex', this._tabindex);

File diff suppressed because one or more lines are too long

View File

@ -238,6 +238,52 @@ $(".js-data-example-ajax").select2({
</div>
</section>
<section id="disabled" class="row">
<div class="col-md-4">
<h1>Disabled mode</h1>
<p>
Select2 will response the <code>disabled</code> attribute on
<code>&lt;select&gt;</code> elements. You can also initialize Select2
with <code>disabled: true</code> to get the same effect.
</p>
<p>
<select class="js-example-disabled js-states form-control" disabled="disabled"></select>
</p>
<p>
<select class="js-example-disabled-multi js-states form-control" multiple="multiple" disabled="disabled"></select>
</p>
<p>
<button class="js-programmatic-enable btn btn-primary">
Enable
</button>
<button class="js-programmatic-disable btn btn-warning">
Disable
</button>
</p>
</div>
<div class="col-md-8">
<h2>Example code</h2>
<pre data-fill-from=".js-code-disabled"></pre>
<script type="text/javascript" class="js-code-disabled">
$(".js-programmatic-enable").on("click", function () {
$(".js-example-disabled").prop("disabled", false);
$(".js-example-disabled-multi").prop("disabled", false);
});
$(".js-programmatic-disable").on("click", function () {
$(".js-example-disabled").prop("disabled", true);
$(".js-example-disabled-multi").prop("disabled", true);
});
</script>
</div>
</section>
<section id="disabled-results" class="row">
<div class="col-md-4">
<h1>Disabled results</h1>
@ -256,7 +302,6 @@ $(".js-data-example-ajax").select2({
<option value="three">Third</option>
</select>
</p>
</div>
<div class="col-md-8">
<h2>Example code</h2>
@ -703,6 +748,9 @@ $.fn.select2.amd.require(
}
});
$(".js-example-disabled").select2();
$(".js-example-disabled-multi").select2();
$disabledResults.select2();
$(".js-example-programmatic").select2();

View File

@ -64,7 +64,6 @@ define([
this._registerEvents();
// Set the initial state
this.data.current(function (initialData) {
self.trigger('selection:update', {
data: initialData
@ -72,9 +71,11 @@ define([
});
// Hide the original select
$element.hide();
// Synchronize any monitored attributes
this._syncAttributes();
this._tabindex = $element.attr('tabindex') || 0;
$element.attr('tabindex', '-1');
@ -123,6 +124,27 @@ define([
});
});
});
this._sync = Utils.bind(this._syncAttributes, this);
if (this.$element[0].attachEvent) {
this.$element[0].attachEvent('onpropertychange', this._sync);
}
var observer = window.MutationObserver ||
window.WebKitMutationObserver ||
window.MozMutationObserver
;
if (observer != null) {
this._observer = new observer(function (mutations) {
$.each(mutations, self._sync);
});
this._observer.observe(this.$element[0], {
attributes: true,
subtree: false
});
}
};
Select2.prototype._registerDataEvents = function () {
@ -218,6 +240,14 @@ define([
self.$container.removeClass('select2-container--open');
});
this.on('enable', function () {
self.$container.removeClass('select2-container--disabled');
});
this.on('disable', function () {
self.$container.addClass('select2-container--disabled');
});
this.on('query', function (params) {
this.data.query(params, function (data) {
self.trigger('results:all', {
@ -267,7 +297,25 @@ define([
});
};
Select2.prototype._syncAttributes = function () {
this.options.set('disabled', this.$element.prop('disabled'));
if (this.options.get('disabled')) {
if (this.isOpen()) {
this.trigger('close');
}
this.trigger('disable');
} else {
this.trigger('enable');
}
};
Select2.prototype.toggleDropdown = function () {
if (this.options.get('disabled')) {
return;
}
if (this.isOpen()) {
this.close();
} else {
@ -341,6 +389,17 @@ define([
Select2.prototype.destroy = function () {
this.$container.remove();
if (this.$element[0].detachEvent) {
this.$element[0].detachEvent('onpropertychange', this._sync);
}
if (this._observer != null) {
this._observer.disconnect();
this._observer = null;
}
this._sync = null;
this.$element.off('.select2');
this.$element.attr('tabindex', this._tabindex);

View File

@ -19,6 +19,10 @@ define([
this.options.multiple = $e.prop('multiple');
}
if (this.options.disabled == null) {
this.options.disabled = $e.prop('disabled');
}
if (this.options.language == null) {
if ($e.prop('lang')) {
this.options.language = $e.prop('lang').toLowerCase();
@ -27,6 +31,9 @@ define([
}
}
$e.prop('disabled', this.options.disabled);
$e.prop('multiple', this.options.multiple);
var data = $e.data();
function convertData (data) {

View File

@ -47,6 +47,14 @@ define([
data: data
});
});
container.on('enable', function () {
self.$selection.attr('tabindex', '0');
});
container.on('disable', function () {
self.$selection.attr('tabindex', '-1');
});
};
MultipleSelection.prototype.clear = function () {

View File

@ -39,6 +39,14 @@ define([
self.$search.val('');
});
container.on('enable', function () {
self.$search.prop('disabled', false);
});
container.on('disable', function () {
self.$search.prop('disabled', true);
});
this.$selection.on('keydown', '.select2-search--inline', function (evt) {
evt.stopPropagation();

View File

@ -57,6 +57,14 @@ define([
// User exits the container
});
container.on('enable', function () {
self.$selection.attr('tabindex', '0');
});
container.on('disable', function () {
self.$selection.attr('tabindex', '-1');
});
container.on('selection:update', function (params) {
self.update(params.data);
});

View File

@ -153,5 +153,11 @@ define([], function () {
return chars;
};
Utils.bind = function (func, context) {
return function () {
func.apply(context, arguments);
};
};
return Utils;
});

View File

@ -46,3 +46,10 @@
}
}
}
&.select2-container--disabled {
.select2-selection--multiple {
background-color: #eee;
cursor: default;
}
}

View File

@ -47,6 +47,13 @@
}
}
&.select2-container--disabled {
.select2-selection--single {
background-color: #eee;
cursor: default;
}
}
&.select2-container--open {
.select2-selection--single {
.select2-selection__arrow {

View File

@ -24,6 +24,7 @@
.select2-search--inline {
.select2-search__field {
background: transparent;
border: none;
outline: 0;
}