Improve data array speeds
This improves the speeds of creating the `<option>` tags for array data. By creating the HTML ahead of time and putting it into an `<option>` element before passing it to jQuery, it cuts down on the time it takes for jQuery to process the HTML string and convert it into DOM elements. This proved to be incredibly slow. This also changes the `item` function to return early when the data exists. The `$e.data` call has also been switched to a `$.data` call, which doesn't need to check the DOM to see if the data attributes already exist. This cuts down on a bit of wasted time, as the `data` key should never be present in the DOM, and it should be ignored if it is.
This commit is contained in:
parent
56dbbf8cdb
commit
05ddbec1a7
57
dist/js/select2.amd.full.js
vendored
57
dist/js/select2.amd.full.js
vendored
@ -1098,30 +1098,41 @@ define('select2/data/select',[
|
|||||||
};
|
};
|
||||||
|
|
||||||
SelectAdapter.prototype.option = function (data) {
|
SelectAdapter.prototype.option = function (data) {
|
||||||
var $option = $('<option></option>');
|
var option = document.createElement('option');
|
||||||
|
|
||||||
$option.text(data.text);
|
option.value = data.id;
|
||||||
$option.val(data.id);
|
|
||||||
$option.prop('disabled', data.disabled || false);
|
|
||||||
$option.prop('selected', data.selected || false);
|
|
||||||
|
|
||||||
// Get any automatically generated data values
|
if (data.disabled) {
|
||||||
var detectedData = this.item($option);
|
option.disabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Merge it with the already present data
|
if (data.selected) {
|
||||||
var combinedData = $.extend({}, data, detectedData);
|
option.selected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
option.innerText = data.text;
|
||||||
|
|
||||||
|
var $option = $(option);
|
||||||
|
|
||||||
|
var normalizedData = this._normalizeItem(data);
|
||||||
|
|
||||||
// Override the option's data with the combined data
|
// Override the option's data with the combined data
|
||||||
$option.data('data', combinedData);
|
$.data($option, normalizedData);
|
||||||
|
|
||||||
return $option;
|
return $option;
|
||||||
};
|
};
|
||||||
|
|
||||||
SelectAdapter.prototype.item = function ($option) {
|
SelectAdapter.prototype.item = function ($option) {
|
||||||
var data = $option.data('data');
|
var data = {};
|
||||||
|
|
||||||
|
if ($.hasData($option)) {
|
||||||
|
data = $option.data('data');
|
||||||
|
|
||||||
|
if (data != null) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If the data has already be generated, use it
|
|
||||||
if (data == null) {
|
|
||||||
if ($option.is('option')) {
|
if ($option.is('option')) {
|
||||||
data = {
|
data = {
|
||||||
id: $option.val(),
|
id: $option.val(),
|
||||||
@ -1148,18 +1159,26 @@ define('select2/data/select',[
|
|||||||
data.children = children;
|
data.children = children;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.id && this.container != null) {
|
data = this._normalizeItem(data);
|
||||||
data._resultId = this.generateResultId(this.container, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
data.selected = $option.prop('selected');
|
|
||||||
|
|
||||||
$option.data('data', data);
|
$option.data('data', data);
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
SelectAdapter.prototype._normalizeItem = function (item) {
|
||||||
|
var defaults = {
|
||||||
|
selected: false,
|
||||||
|
disabled: false
|
||||||
|
};
|
||||||
|
|
||||||
|
if (item._resultId == null && item.id && this.container != null) {
|
||||||
|
item._resultId = this.generateResultId(this.container, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $.extend({}, defaults, item);
|
||||||
|
};
|
||||||
|
|
||||||
SelectAdapter.prototype.matches = function (params, data) {
|
SelectAdapter.prototype.matches = function (params, data) {
|
||||||
var matcher = this.options.get('matcher');
|
var matcher = this.options.get('matcher');
|
||||||
|
|
||||||
|
57
dist/js/select2.amd.js
vendored
57
dist/js/select2.amd.js
vendored
@ -1098,30 +1098,41 @@ define('select2/data/select',[
|
|||||||
};
|
};
|
||||||
|
|
||||||
SelectAdapter.prototype.option = function (data) {
|
SelectAdapter.prototype.option = function (data) {
|
||||||
var $option = $('<option></option>');
|
var option = document.createElement('option');
|
||||||
|
|
||||||
$option.text(data.text);
|
option.value = data.id;
|
||||||
$option.val(data.id);
|
|
||||||
$option.prop('disabled', data.disabled || false);
|
|
||||||
$option.prop('selected', data.selected || false);
|
|
||||||
|
|
||||||
// Get any automatically generated data values
|
if (data.disabled) {
|
||||||
var detectedData = this.item($option);
|
option.disabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Merge it with the already present data
|
if (data.selected) {
|
||||||
var combinedData = $.extend({}, data, detectedData);
|
option.selected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
option.innerText = data.text;
|
||||||
|
|
||||||
|
var $option = $(option);
|
||||||
|
|
||||||
|
var normalizedData = this._normalizeItem(data);
|
||||||
|
|
||||||
// Override the option's data with the combined data
|
// Override the option's data with the combined data
|
||||||
$option.data('data', combinedData);
|
$.data($option, normalizedData);
|
||||||
|
|
||||||
return $option;
|
return $option;
|
||||||
};
|
};
|
||||||
|
|
||||||
SelectAdapter.prototype.item = function ($option) {
|
SelectAdapter.prototype.item = function ($option) {
|
||||||
var data = $option.data('data');
|
var data = {};
|
||||||
|
|
||||||
|
if ($.hasData($option)) {
|
||||||
|
data = $option.data('data');
|
||||||
|
|
||||||
|
if (data != null) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If the data has already be generated, use it
|
|
||||||
if (data == null) {
|
|
||||||
if ($option.is('option')) {
|
if ($option.is('option')) {
|
||||||
data = {
|
data = {
|
||||||
id: $option.val(),
|
id: $option.val(),
|
||||||
@ -1148,18 +1159,26 @@ define('select2/data/select',[
|
|||||||
data.children = children;
|
data.children = children;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.id && this.container != null) {
|
data = this._normalizeItem(data);
|
||||||
data._resultId = this.generateResultId(this.container, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
data.selected = $option.prop('selected');
|
|
||||||
|
|
||||||
$option.data('data', data);
|
$option.data('data', data);
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
SelectAdapter.prototype._normalizeItem = function (item) {
|
||||||
|
var defaults = {
|
||||||
|
selected: false,
|
||||||
|
disabled: false
|
||||||
|
};
|
||||||
|
|
||||||
|
if (item._resultId == null && item.id && this.container != null) {
|
||||||
|
item._resultId = this.generateResultId(this.container, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $.extend({}, defaults, item);
|
||||||
|
};
|
||||||
|
|
||||||
SelectAdapter.prototype.matches = function (params, data) {
|
SelectAdapter.prototype.matches = function (params, data) {
|
||||||
var matcher = this.options.get('matcher');
|
var matcher = this.options.get('matcher');
|
||||||
|
|
||||||
|
57
dist/js/select2.full.js
vendored
57
dist/js/select2.full.js
vendored
@ -10633,30 +10633,41 @@ define('select2/data/select',[
|
|||||||
};
|
};
|
||||||
|
|
||||||
SelectAdapter.prototype.option = function (data) {
|
SelectAdapter.prototype.option = function (data) {
|
||||||
var $option = $('<option></option>');
|
var option = document.createElement('option');
|
||||||
|
|
||||||
$option.text(data.text);
|
option.value = data.id;
|
||||||
$option.val(data.id);
|
|
||||||
$option.prop('disabled', data.disabled || false);
|
|
||||||
$option.prop('selected', data.selected || false);
|
|
||||||
|
|
||||||
// Get any automatically generated data values
|
if (data.disabled) {
|
||||||
var detectedData = this.item($option);
|
option.disabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Merge it with the already present data
|
if (data.selected) {
|
||||||
var combinedData = $.extend({}, data, detectedData);
|
option.selected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
option.innerText = data.text;
|
||||||
|
|
||||||
|
var $option = $(option);
|
||||||
|
|
||||||
|
var normalizedData = this._normalizeItem(data);
|
||||||
|
|
||||||
// Override the option's data with the combined data
|
// Override the option's data with the combined data
|
||||||
$option.data('data', combinedData);
|
$.data($option, normalizedData);
|
||||||
|
|
||||||
return $option;
|
return $option;
|
||||||
};
|
};
|
||||||
|
|
||||||
SelectAdapter.prototype.item = function ($option) {
|
SelectAdapter.prototype.item = function ($option) {
|
||||||
var data = $option.data('data');
|
var data = {};
|
||||||
|
|
||||||
|
if ($.hasData($option)) {
|
||||||
|
data = $option.data('data');
|
||||||
|
|
||||||
|
if (data != null) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If the data has already be generated, use it
|
|
||||||
if (data == null) {
|
|
||||||
if ($option.is('option')) {
|
if ($option.is('option')) {
|
||||||
data = {
|
data = {
|
||||||
id: $option.val(),
|
id: $option.val(),
|
||||||
@ -10683,18 +10694,26 @@ define('select2/data/select',[
|
|||||||
data.children = children;
|
data.children = children;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.id && this.container != null) {
|
data = this._normalizeItem(data);
|
||||||
data._resultId = this.generateResultId(this.container, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
data.selected = $option.prop('selected');
|
|
||||||
|
|
||||||
$option.data('data', data);
|
$option.data('data', data);
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
SelectAdapter.prototype._normalizeItem = function (item) {
|
||||||
|
var defaults = {
|
||||||
|
selected: false,
|
||||||
|
disabled: false
|
||||||
|
};
|
||||||
|
|
||||||
|
if (item._resultId == null && item.id && this.container != null) {
|
||||||
|
item._resultId = this.generateResultId(this.container, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $.extend({}, defaults, item);
|
||||||
|
};
|
||||||
|
|
||||||
SelectAdapter.prototype.matches = function (params, data) {
|
SelectAdapter.prototype.matches = function (params, data) {
|
||||||
var matcher = this.options.get('matcher');
|
var matcher = this.options.get('matcher');
|
||||||
|
|
||||||
|
2
dist/js/select2.full.min.js
vendored
2
dist/js/select2.full.min.js
vendored
File diff suppressed because one or more lines are too long
57
dist/js/select2.js
vendored
57
dist/js/select2.js
vendored
@ -1526,30 +1526,41 @@ define('select2/data/select',[
|
|||||||
};
|
};
|
||||||
|
|
||||||
SelectAdapter.prototype.option = function (data) {
|
SelectAdapter.prototype.option = function (data) {
|
||||||
var $option = $('<option></option>');
|
var option = document.createElement('option');
|
||||||
|
|
||||||
$option.text(data.text);
|
option.value = data.id;
|
||||||
$option.val(data.id);
|
|
||||||
$option.prop('disabled', data.disabled || false);
|
|
||||||
$option.prop('selected', data.selected || false);
|
|
||||||
|
|
||||||
// Get any automatically generated data values
|
if (data.disabled) {
|
||||||
var detectedData = this.item($option);
|
option.disabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Merge it with the already present data
|
if (data.selected) {
|
||||||
var combinedData = $.extend({}, data, detectedData);
|
option.selected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
option.innerText = data.text;
|
||||||
|
|
||||||
|
var $option = $(option);
|
||||||
|
|
||||||
|
var normalizedData = this._normalizeItem(data);
|
||||||
|
|
||||||
// Override the option's data with the combined data
|
// Override the option's data with the combined data
|
||||||
$option.data('data', combinedData);
|
$.data($option, normalizedData);
|
||||||
|
|
||||||
return $option;
|
return $option;
|
||||||
};
|
};
|
||||||
|
|
||||||
SelectAdapter.prototype.item = function ($option) {
|
SelectAdapter.prototype.item = function ($option) {
|
||||||
var data = $option.data('data');
|
var data = {};
|
||||||
|
|
||||||
|
if ($.hasData($option)) {
|
||||||
|
data = $option.data('data');
|
||||||
|
|
||||||
|
if (data != null) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If the data has already be generated, use it
|
|
||||||
if (data == null) {
|
|
||||||
if ($option.is('option')) {
|
if ($option.is('option')) {
|
||||||
data = {
|
data = {
|
||||||
id: $option.val(),
|
id: $option.val(),
|
||||||
@ -1576,18 +1587,26 @@ define('select2/data/select',[
|
|||||||
data.children = children;
|
data.children = children;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.id && this.container != null) {
|
data = this._normalizeItem(data);
|
||||||
data._resultId = this.generateResultId(this.container, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
data.selected = $option.prop('selected');
|
|
||||||
|
|
||||||
$option.data('data', data);
|
$option.data('data', data);
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
SelectAdapter.prototype._normalizeItem = function (item) {
|
||||||
|
var defaults = {
|
||||||
|
selected: false,
|
||||||
|
disabled: false
|
||||||
|
};
|
||||||
|
|
||||||
|
if (item._resultId == null && item.id && this.container != null) {
|
||||||
|
item._resultId = this.generateResultId(this.container, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $.extend({}, defaults, item);
|
||||||
|
};
|
||||||
|
|
||||||
SelectAdapter.prototype.matches = function (params, data) {
|
SelectAdapter.prototype.matches = function (params, data) {
|
||||||
var matcher = this.options.get('matcher');
|
var matcher = this.options.get('matcher');
|
||||||
|
|
||||||
|
2
dist/js/select2.min.js
vendored
2
dist/js/select2.min.js
vendored
File diff suppressed because one or more lines are too long
57
src/js/select2/data/select.js
vendored
57
src/js/select2/data/select.js
vendored
@ -121,30 +121,41 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
SelectAdapter.prototype.option = function (data) {
|
SelectAdapter.prototype.option = function (data) {
|
||||||
var $option = $('<option></option>');
|
var option = document.createElement('option');
|
||||||
|
|
||||||
$option.text(data.text);
|
option.value = data.id;
|
||||||
$option.val(data.id);
|
|
||||||
$option.prop('disabled', data.disabled || false);
|
|
||||||
$option.prop('selected', data.selected || false);
|
|
||||||
|
|
||||||
// Get any automatically generated data values
|
if (data.disabled) {
|
||||||
var detectedData = this.item($option);
|
option.disabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Merge it with the already present data
|
if (data.selected) {
|
||||||
var combinedData = $.extend({}, data, detectedData);
|
option.selected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
option.innerText = data.text;
|
||||||
|
|
||||||
|
var $option = $(option);
|
||||||
|
|
||||||
|
var normalizedData = this._normalizeItem(data);
|
||||||
|
|
||||||
// Override the option's data with the combined data
|
// Override the option's data with the combined data
|
||||||
$option.data('data', combinedData);
|
$.data($option, normalizedData);
|
||||||
|
|
||||||
return $option;
|
return $option;
|
||||||
};
|
};
|
||||||
|
|
||||||
SelectAdapter.prototype.item = function ($option) {
|
SelectAdapter.prototype.item = function ($option) {
|
||||||
var data = $option.data('data');
|
var data = {};
|
||||||
|
|
||||||
|
if ($.hasData($option)) {
|
||||||
|
data = $option.data('data');
|
||||||
|
|
||||||
|
if (data != null) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If the data has already be generated, use it
|
|
||||||
if (data == null) {
|
|
||||||
if ($option.is('option')) {
|
if ($option.is('option')) {
|
||||||
data = {
|
data = {
|
||||||
id: $option.val(),
|
id: $option.val(),
|
||||||
@ -171,18 +182,26 @@ define([
|
|||||||
data.children = children;
|
data.children = children;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.id && this.container != null) {
|
data = this._normalizeItem(data);
|
||||||
data._resultId = this.generateResultId(this.container, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
data.selected = $option.prop('selected');
|
|
||||||
|
|
||||||
$option.data('data', data);
|
$option.data('data', data);
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
SelectAdapter.prototype._normalizeItem = function (item) {
|
||||||
|
var defaults = {
|
||||||
|
selected: false,
|
||||||
|
disabled: false
|
||||||
|
};
|
||||||
|
|
||||||
|
if (item._resultId == null && item.id && this.container != null) {
|
||||||
|
item._resultId = this.generateResultId(this.container, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $.extend({}, defaults, item);
|
||||||
|
};
|
||||||
|
|
||||||
SelectAdapter.prototype.matches = function (params, data) {
|
SelectAdapter.prototype.matches = function (params, data) {
|
||||||
var matcher = this.options.get('matcher');
|
var matcher = this.options.get('matcher');
|
||||||
|
|
||||||
|
@ -238,13 +238,24 @@ test('empty optgroups are still shown when queried', function (assert) {
|
|||||||
var data = new SelectData($select, options);
|
var data = new SelectData($select, options);
|
||||||
|
|
||||||
data.query({}, function (data) {
|
data.query({}, function (data) {
|
||||||
assert.deepEqual(
|
assert.equal(
|
||||||
data[1],
|
data.length,
|
||||||
{
|
2,
|
||||||
text: 'Empty',
|
|
||||||
children: []
|
|
||||||
},
|
|
||||||
'The empty optgroup element should still be returned when queried'
|
'The empty optgroup element should still be returned when queried'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
var item = data[1];
|
||||||
|
|
||||||
|
assert.equal(
|
||||||
|
item.text,
|
||||||
|
'Empty',
|
||||||
|
'The text of the empty optgroup should match the label'
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.equal(
|
||||||
|
item.children.length,
|
||||||
|
0,
|
||||||
|
'There should be no children in the empty opgroup'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user