1
0
mirror of synced 2024-11-26 06:46:04 +03:00

Added destroy method

Now Select2 supports destroying itself, and all elements that it
creates.
This commit is contained in:
Kevin Brown 2014-11-13 18:34:08 -05:00
parent 78ee1bc01e
commit a2766b7ed6
13 changed files with 294 additions and 8 deletions

View File

@ -520,6 +520,10 @@ define('select2/results',[
}); });
}; };
Results.prototype.destroy = function () {
this.$results.remove();
};
Results.prototype.ensureHighlightVisible = function () { Results.prototype.ensureHighlightVisible = function () {
var $highlighted = this.$results.find('.highlighted'); var $highlighted = this.$results.find('.highlighted');
@ -604,6 +608,11 @@ define('select2/selection/base',[
}); });
}; };
BaseSelection.prototype.destroy = function () {
// Unbind the dropdown click handler if it exists
$(document.body).off('.select2.' + container.id);
};
BaseSelection.prototype.update = function (data) { BaseSelection.prototype.update = function (data) {
throw new Error('The `update` method must be defined in child classes.'); throw new Error('The `update` method must be defined in child classes.');
}; };
@ -961,6 +970,10 @@ define('select2/data/base',[
// Can be implemented in subclasses // Can be implemented in subclasses
}; };
BaseAdapter.prototype.destroy = function () {
// Can be implemented in subclasses
};
BaseAdapter.prototype.generateResultId = function (container, data) { BaseAdapter.prototype.generateResultId = function (container, data) {
var id = container.id + '-result-'; var id = container.id + '-result-';
@ -1074,6 +1087,14 @@ define('select2/data/select',[
}); });
}; };
SelectAdapter.prototype.destroy = function () {
// Remove anything added to child elements
this.$element.find('*').each(function () {
// Remove any custom data set by Select2
$.removeData(this, 'data');
});
};
SelectAdapter.prototype.query = function (params, callback) { SelectAdapter.prototype.query = function (params, callback) {
var data = []; var data = [];
var self = this; var self = this;
@ -1479,9 +1500,16 @@ define('select2/dropdown',[
'</span>' '</span>'
); );
this.$dropdown = $dropdown;
return $dropdown; return $dropdown;
}; };
Dropdown.prototype.destroy = function () {
// Remove the dropdown from the DOM
this.$dropdown.remove();
};
Dropdown.prototype.bind = function (container, $container) { Dropdown.prototype.bind = function (container, $container) {
// Can be implemented in subclasses // Can be implemented in subclasses
}; };
@ -1950,6 +1978,10 @@ define('select2/core',[
'./keys' './keys'
], function ($, Options, Utils, KEYS) { ], function ($, Options, Utils, KEYS) {
var Select2 = function ($element, options) { var Select2 = function ($element, options) {
if ($element.data('select2') != null) {
return;
}
this.$element = $element; this.$element = $element;
this.id = this._generateId($element); this.id = this._generateId($element);
@ -2018,6 +2050,9 @@ define('select2/core',[
// Hide the original select // Hide the original select
$element.hide(); $element.hide();
this._tabindex = $element.attr('tabindex') || 0;
$element.attr('tabindex', '-1'); $element.attr('tabindex', '-1');
$element.data('select2', this); $element.data('select2', this);
@ -2074,7 +2109,7 @@ define('select2/core',[
Select2.prototype._registerDomEvents = function () { Select2.prototype._registerDomEvents = function () {
var self = this; var self = this;
this.$element.on('change', function () { this.$element.on('change.select2', function () {
self.data.current(function (data) { self.data.current(function (data) {
self.trigger('selection:update', { self.trigger('selection:update', {
data: data data: data
@ -2251,6 +2286,26 @@ define('select2/core',[
return this.$container.hasClass('open'); return this.$container.hasClass('open');
}; };
Select2.prototype.destroy = function () {
this.$container.remove();
this.$element.off('.select2');
this.$element.attr('tabindex', this._tabindex);
this.$element.show();
this.$element.removeData('select2');
this.data.destroy();
this.selection.destroy();
this.dropdown.destroy();
this.results.destroy();
this.data = null;
this.selection = null;
this.dropdown = null;
this.results = null;
};
Select2.prototype.render = function () { Select2.prototype.render = function () {
var $container = $( var $container = $(
'<span class="select2 select2-container select2-theme-default">' + '<span class="select2 select2-container select2-theme-default">' +

View File

@ -520,6 +520,10 @@ define('select2/results',[
}); });
}; };
Results.prototype.destroy = function () {
this.$results.remove();
};
Results.prototype.ensureHighlightVisible = function () { Results.prototype.ensureHighlightVisible = function () {
var $highlighted = this.$results.find('.highlighted'); var $highlighted = this.$results.find('.highlighted');
@ -604,6 +608,11 @@ define('select2/selection/base',[
}); });
}; };
BaseSelection.prototype.destroy = function () {
// Unbind the dropdown click handler if it exists
$(document.body).off('.select2.' + container.id);
};
BaseSelection.prototype.update = function (data) { BaseSelection.prototype.update = function (data) {
throw new Error('The `update` method must be defined in child classes.'); throw new Error('The `update` method must be defined in child classes.');
}; };
@ -961,6 +970,10 @@ define('select2/data/base',[
// Can be implemented in subclasses // Can be implemented in subclasses
}; };
BaseAdapter.prototype.destroy = function () {
// Can be implemented in subclasses
};
BaseAdapter.prototype.generateResultId = function (container, data) { BaseAdapter.prototype.generateResultId = function (container, data) {
var id = container.id + '-result-'; var id = container.id + '-result-';
@ -1074,6 +1087,14 @@ define('select2/data/select',[
}); });
}; };
SelectAdapter.prototype.destroy = function () {
// Remove anything added to child elements
this.$element.find('*').each(function () {
// Remove any custom data set by Select2
$.removeData(this, 'data');
});
};
SelectAdapter.prototype.query = function (params, callback) { SelectAdapter.prototype.query = function (params, callback) {
var data = []; var data = [];
var self = this; var self = this;
@ -1479,9 +1500,16 @@ define('select2/dropdown',[
'</span>' '</span>'
); );
this.$dropdown = $dropdown;
return $dropdown; return $dropdown;
}; };
Dropdown.prototype.destroy = function () {
// Remove the dropdown from the DOM
this.$dropdown.remove();
};
Dropdown.prototype.bind = function (container, $container) { Dropdown.prototype.bind = function (container, $container) {
// Can be implemented in subclasses // Can be implemented in subclasses
}; };
@ -1950,6 +1978,10 @@ define('select2/core',[
'./keys' './keys'
], function ($, Options, Utils, KEYS) { ], function ($, Options, Utils, KEYS) {
var Select2 = function ($element, options) { var Select2 = function ($element, options) {
if ($element.data('select2') != null) {
return;
}
this.$element = $element; this.$element = $element;
this.id = this._generateId($element); this.id = this._generateId($element);
@ -2018,6 +2050,9 @@ define('select2/core',[
// Hide the original select // Hide the original select
$element.hide(); $element.hide();
this._tabindex = $element.attr('tabindex') || 0;
$element.attr('tabindex', '-1'); $element.attr('tabindex', '-1');
$element.data('select2', this); $element.data('select2', this);
@ -2074,7 +2109,7 @@ define('select2/core',[
Select2.prototype._registerDomEvents = function () { Select2.prototype._registerDomEvents = function () {
var self = this; var self = this;
this.$element.on('change', function () { this.$element.on('change.select2', function () {
self.data.current(function (data) { self.data.current(function (data) {
self.trigger('selection:update', { self.trigger('selection:update', {
data: data data: data
@ -2251,6 +2286,26 @@ define('select2/core',[
return this.$container.hasClass('open'); return this.$container.hasClass('open');
}; };
Select2.prototype.destroy = function () {
this.$container.remove();
this.$element.off('.select2');
this.$element.attr('tabindex', this._tabindex);
this.$element.show();
this.$element.removeData('select2');
this.data.destroy();
this.selection.destroy();
this.dropdown.destroy();
this.results.destroy();
this.data = null;
this.selection = null;
this.dropdown = null;
this.results = null;
};
Select2.prototype.render = function () { Select2.prototype.render = function () {
var $container = $( var $container = $(
'<span class="select2 select2-container select2-theme-default">' + '<span class="select2 select2-container select2-theme-default">' +

View File

@ -10055,6 +10055,10 @@ define('select2/results',[
}); });
}; };
Results.prototype.destroy = function () {
this.$results.remove();
};
Results.prototype.ensureHighlightVisible = function () { Results.prototype.ensureHighlightVisible = function () {
var $highlighted = this.$results.find('.highlighted'); var $highlighted = this.$results.find('.highlighted');
@ -10139,6 +10143,11 @@ define('select2/selection/base',[
}); });
}; };
BaseSelection.prototype.destroy = function () {
// Unbind the dropdown click handler if it exists
$(document.body).off('.select2.' + container.id);
};
BaseSelection.prototype.update = function (data) { BaseSelection.prototype.update = function (data) {
throw new Error('The `update` method must be defined in child classes.'); throw new Error('The `update` method must be defined in child classes.');
}; };
@ -10496,6 +10505,10 @@ define('select2/data/base',[
// Can be implemented in subclasses // Can be implemented in subclasses
}; };
BaseAdapter.prototype.destroy = function () {
// Can be implemented in subclasses
};
BaseAdapter.prototype.generateResultId = function (container, data) { BaseAdapter.prototype.generateResultId = function (container, data) {
var id = container.id + '-result-'; var id = container.id + '-result-';
@ -10609,6 +10622,14 @@ define('select2/data/select',[
}); });
}; };
SelectAdapter.prototype.destroy = function () {
// Remove anything added to child elements
this.$element.find('*').each(function () {
// Remove any custom data set by Select2
$.removeData(this, 'data');
});
};
SelectAdapter.prototype.query = function (params, callback) { SelectAdapter.prototype.query = function (params, callback) {
var data = []; var data = [];
var self = this; var self = this;
@ -11014,9 +11035,16 @@ define('select2/dropdown',[
'</span>' '</span>'
); );
this.$dropdown = $dropdown;
return $dropdown; return $dropdown;
}; };
Dropdown.prototype.destroy = function () {
// Remove the dropdown from the DOM
this.$dropdown.remove();
};
Dropdown.prototype.bind = function (container, $container) { Dropdown.prototype.bind = function (container, $container) {
// Can be implemented in subclasses // Can be implemented in subclasses
}; };
@ -11485,6 +11513,10 @@ define('select2/core',[
'./keys' './keys'
], function ($, Options, Utils, KEYS) { ], function ($, Options, Utils, KEYS) {
var Select2 = function ($element, options) { var Select2 = function ($element, options) {
if ($element.data('select2') != null) {
return;
}
this.$element = $element; this.$element = $element;
this.id = this._generateId($element); this.id = this._generateId($element);
@ -11553,6 +11585,9 @@ define('select2/core',[
// Hide the original select // Hide the original select
$element.hide(); $element.hide();
this._tabindex = $element.attr('tabindex') || 0;
$element.attr('tabindex', '-1'); $element.attr('tabindex', '-1');
$element.data('select2', this); $element.data('select2', this);
@ -11609,7 +11644,7 @@ define('select2/core',[
Select2.prototype._registerDomEvents = function () { Select2.prototype._registerDomEvents = function () {
var self = this; var self = this;
this.$element.on('change', function () { this.$element.on('change.select2', function () {
self.data.current(function (data) { self.data.current(function (data) {
self.trigger('selection:update', { self.trigger('selection:update', {
data: data data: data
@ -11786,6 +11821,26 @@ define('select2/core',[
return this.$container.hasClass('open'); return this.$container.hasClass('open');
}; };
Select2.prototype.destroy = function () {
this.$container.remove();
this.$element.off('.select2');
this.$element.attr('tabindex', this._tabindex);
this.$element.show();
this.$element.removeData('select2');
this.data.destroy();
this.selection.destroy();
this.dropdown.destroy();
this.results.destroy();
this.data = null;
this.selection = null;
this.dropdown = null;
this.results = null;
};
Select2.prototype.render = function () { Select2.prototype.render = function () {
var $container = $( var $container = $(
'<span class="select2 select2-container select2-theme-default">' + '<span class="select2 select2-container select2-theme-default">' +

File diff suppressed because one or more lines are too long

57
dist/js/select2.js vendored
View File

@ -948,6 +948,10 @@ define('select2/results',[
}); });
}; };
Results.prototype.destroy = function () {
this.$results.remove();
};
Results.prototype.ensureHighlightVisible = function () { Results.prototype.ensureHighlightVisible = function () {
var $highlighted = this.$results.find('.highlighted'); var $highlighted = this.$results.find('.highlighted');
@ -1032,6 +1036,11 @@ define('select2/selection/base',[
}); });
}; };
BaseSelection.prototype.destroy = function () {
// Unbind the dropdown click handler if it exists
$(document.body).off('.select2.' + container.id);
};
BaseSelection.prototype.update = function (data) { BaseSelection.prototype.update = function (data) {
throw new Error('The `update` method must be defined in child classes.'); throw new Error('The `update` method must be defined in child classes.');
}; };
@ -1389,6 +1398,10 @@ define('select2/data/base',[
// Can be implemented in subclasses // Can be implemented in subclasses
}; };
BaseAdapter.prototype.destroy = function () {
// Can be implemented in subclasses
};
BaseAdapter.prototype.generateResultId = function (container, data) { BaseAdapter.prototype.generateResultId = function (container, data) {
var id = container.id + '-result-'; var id = container.id + '-result-';
@ -1502,6 +1515,14 @@ define('select2/data/select',[
}); });
}; };
SelectAdapter.prototype.destroy = function () {
// Remove anything added to child elements
this.$element.find('*').each(function () {
// Remove any custom data set by Select2
$.removeData(this, 'data');
});
};
SelectAdapter.prototype.query = function (params, callback) { SelectAdapter.prototype.query = function (params, callback) {
var data = []; var data = [];
var self = this; var self = this;
@ -1907,9 +1928,16 @@ define('select2/dropdown',[
'</span>' '</span>'
); );
this.$dropdown = $dropdown;
return $dropdown; return $dropdown;
}; };
Dropdown.prototype.destroy = function () {
// Remove the dropdown from the DOM
this.$dropdown.remove();
};
Dropdown.prototype.bind = function (container, $container) { Dropdown.prototype.bind = function (container, $container) {
// Can be implemented in subclasses // Can be implemented in subclasses
}; };
@ -2378,6 +2406,10 @@ define('select2/core',[
'./keys' './keys'
], function ($, Options, Utils, KEYS) { ], function ($, Options, Utils, KEYS) {
var Select2 = function ($element, options) { var Select2 = function ($element, options) {
if ($element.data('select2') != null) {
return;
}
this.$element = $element; this.$element = $element;
this.id = this._generateId($element); this.id = this._generateId($element);
@ -2446,6 +2478,9 @@ define('select2/core',[
// Hide the original select // Hide the original select
$element.hide(); $element.hide();
this._tabindex = $element.attr('tabindex') || 0;
$element.attr('tabindex', '-1'); $element.attr('tabindex', '-1');
$element.data('select2', this); $element.data('select2', this);
@ -2502,7 +2537,7 @@ define('select2/core',[
Select2.prototype._registerDomEvents = function () { Select2.prototype._registerDomEvents = function () {
var self = this; var self = this;
this.$element.on('change', function () { this.$element.on('change.select2', function () {
self.data.current(function (data) { self.data.current(function (data) {
self.trigger('selection:update', { self.trigger('selection:update', {
data: data data: data
@ -2679,6 +2714,26 @@ define('select2/core',[
return this.$container.hasClass('open'); return this.$container.hasClass('open');
}; };
Select2.prototype.destroy = function () {
this.$container.remove();
this.$element.off('.select2');
this.$element.attr('tabindex', this._tabindex);
this.$element.show();
this.$element.removeData('select2');
this.data.destroy();
this.selection.destroy();
this.dropdown.destroy();
this.results.destroy();
this.data = null;
this.selection = null;
this.dropdown = null;
this.results = null;
};
Select2.prototype.render = function () { Select2.prototype.render = function () {
var $container = $( var $container = $(
'<span class="select2 select2-container select2-theme-default">' + '<span class="select2 select2-container select2-theme-default">' +

File diff suppressed because one or more lines are too long

View File

@ -246,6 +246,14 @@ $(".js-example-data-array-selected").select2({
<button class="js-programmatic-close btn btn-success"> <button class="js-programmatic-close btn btn-success">
Close Close
</button> </button>
<button class="js-programmatic-init btn btn-danger">
Init
</button>
<button class="js-programmatic-destroy btn btn-danger">
Destroy
</button>
</p> </p>
<p> <p>
@ -263,6 +271,9 @@ var $example = $(".js-example-programmatic");
$(".js-programmatic-open").on("click", function () { $example.select2("open"); }); $(".js-programmatic-open").on("click", function () { $example.select2("open"); });
$(".js-programmatic-close").on("click", function () { $example.select2("close"); }); $(".js-programmatic-close").on("click", function () { $example.select2("close"); });
$(".js-programmatic-init").on("click", function () { $example.select2(); });
$(".js-programmatic-destroy").on("click", function () { $example.select2("destroy"); });
</script> </script>
</div> </div>
</section> </section>

View File

@ -5,6 +5,10 @@ define([
'./keys' './keys'
], function ($, Options, Utils, KEYS) { ], function ($, Options, Utils, KEYS) {
var Select2 = function ($element, options) { var Select2 = function ($element, options) {
if ($element.data('select2') != null) {
return;
}
this.$element = $element; this.$element = $element;
this.id = this._generateId($element); this.id = this._generateId($element);
@ -73,6 +77,9 @@ define([
// Hide the original select // Hide the original select
$element.hide(); $element.hide();
this._tabindex = $element.attr('tabindex') || 0;
$element.attr('tabindex', '-1'); $element.attr('tabindex', '-1');
$element.data('select2', this); $element.data('select2', this);
@ -129,7 +136,7 @@ define([
Select2.prototype._registerDomEvents = function () { Select2.prototype._registerDomEvents = function () {
var self = this; var self = this;
this.$element.on('change', function () { this.$element.on('change.select2', function () {
self.data.current(function (data) { self.data.current(function (data) {
self.trigger('selection:update', { self.trigger('selection:update', {
data: data data: data
@ -306,6 +313,26 @@ define([
return this.$container.hasClass('open'); return this.$container.hasClass('open');
}; };
Select2.prototype.destroy = function () {
this.$container.remove();
this.$element.off('.select2');
this.$element.attr('tabindex', this._tabindex);
this.$element.show();
this.$element.removeData('select2');
this.data.destroy();
this.selection.destroy();
this.dropdown.destroy();
this.results.destroy();
this.data = null;
this.selection = null;
this.dropdown = null;
this.results = null;
};
Select2.prototype.render = function () { Select2.prototype.render = function () {
var $container = $( var $container = $(
'<span class="select2 select2-container select2-theme-default">' + '<span class="select2 select2-container select2-theme-default">' +

View File

@ -19,6 +19,10 @@ define([
// Can be implemented in subclasses // Can be implemented in subclasses
}; };
BaseAdapter.prototype.destroy = function () {
// Can be implemented in subclasses
};
BaseAdapter.prototype.generateResultId = function (container, data) { BaseAdapter.prototype.generateResultId = function (container, data) {
var id = container.id + '-result-'; var id = container.id + '-result-';

View File

@ -95,6 +95,14 @@ define([
}); });
}; };
SelectAdapter.prototype.destroy = function () {
// Remove anything added to child elements
this.$element.find('*').each(function () {
// Remove any custom data set by Select2
$.removeData(this, 'data');
});
};
SelectAdapter.prototype.query = function (params, callback) { SelectAdapter.prototype.query = function (params, callback) {
var data = []; var data = [];
var self = this; var self = this;

View File

@ -14,9 +14,16 @@ define([
'</span>' '</span>'
); );
this.$dropdown = $dropdown;
return $dropdown; return $dropdown;
}; };
Dropdown.prototype.destroy = function () {
// Remove the dropdown from the DOM
this.$dropdown.remove();
};
Dropdown.prototype.bind = function (container, $container) { Dropdown.prototype.bind = function (container, $container) {
// Can be implemented in subclasses // Can be implemented in subclasses
}; };

View File

@ -366,6 +366,10 @@ define([
}); });
}; };
Results.prototype.destroy = function () {
this.$results.remove();
};
Results.prototype.ensureHighlightVisible = function () { Results.prototype.ensureHighlightVisible = function () {
var $highlighted = this.$results.find('.highlighted'); var $highlighted = this.$results.find('.highlighted');

View File

@ -48,6 +48,11 @@ define([
}); });
}; };
BaseSelection.prototype.destroy = function () {
// Unbind the dropdown click handler if it exists
$(document.body).off('.select2.' + container.id);
};
BaseSelection.prototype.update = function (data) { BaseSelection.prototype.update = function (data) {
throw new Error('The `update` method must be defined in child classes.'); throw new Error('The `update` method must be defined in child classes.');
}; };