1
0
mirror of synced 2024-11-22 04:56:08 +03:00

Pull query and initSelection out to compat modules

This also adds more documentation and corrects the release notes
for these breaking changes. These modules will now only be included
in the full builds of Select2, which has been noted in a few places.
This commit is contained in:
Kevin Brown 2015-01-15 14:36:54 -05:00
parent 061b432485
commit d6a83ea026
13 changed files with 446 additions and 235 deletions

View File

@ -13,6 +13,8 @@ module.exports = function (grunt) {
'jquery.mousewheel',
'select2/compat/matcher',
'select2/compat/initSelection',
'select2/compat/query',
'select2/dropdown/attachContainer'
].concat(includes);

View File

@ -3527,56 +3527,22 @@ define('select2/defaults',[
}
if (options.query != null) {
if (console && console.warn) {
console.warn(
'Select2: The `query` option has been deprecated in favor of a ' +
'custom data adapter that overrides the `query` method. Support ' +
'will be removed for the `query` option in future versions of ' +
'Select2.'
var Query = require(options.amdBase + 'compat/query');
options.dataAdapter = Utils.Decorate(
options.dataAdapter,
Query
);
}
options.dataAdapter.prototype.query = function (params, callback) {
params.callback = callback;
options.query.call(null, params);
};
}
if (options.initSelection != null) {
if (console && console.warn) {
console.warn(
'Select2: The `initSelection` option has been deprecated in favor' +
' of a custom data adapter that overrides the `current` method. ' +
'This method is now called multiple times instead of a single ' +
'time when the instance is initialized. Support will be removed ' +
'for the `initSelection` option in future versions of Select2'
var InitSelection = require(options.amdBase + 'compat/initSelection');
options.dataAdapter = Utils.Decorate(
options.dataAdapter,
InitSelection
);
}
var oldCurrent = options.dataAdapter.prototype.current;
var newCurrent = function (callback) {
var self = this;
if (this._isInitialized) {
oldCurrent.call(this, callback);
return;
}
options.initSelection.call(null, this.$element, function (data) {
self._isInitialized = true;
if (!$.isArray(data)) {
data = [data];
}
callback(data);
});
};
options.dataAdapter.prototype.current = newCurrent;
}
}
if (options.resultsAdapter == null) {
@ -4663,6 +4629,76 @@ define('select2/compat/matcher',[
return oldMatcher;
});
define('select2/compat/initSelection',[
'jquery'
], function ($) {
function InitSelection (decorated, $element, options) {
if (console && console.warn) {
console.warn(
'Select2: The `initSelection` option has been deprecated in favor' +
' of a custom data adapter that overrides the `current` method. ' +
'This method is now called multiple times instead of a single ' +
'time when the instance is initialized. Support will be removed ' +
'for the `initSelection` option in future versions of Select2'
);
}
this.initSelection = options.get('initSelection');
this._isInitialized = false;
decorated.call(this, $element, options);
}
InitSelection.prototype.current = function (decorated, callback) {
var self = this;
if (this._isInitialized) {
decorated.call(this, callback);
return;
}
this.initSelection.call(null, this.$element, function (data) {
self._isInitialized = true;
if (!$.isArray(data)) {
data = [data];
}
callback(data);
});
};
return InitSelection;
});
define('select2/compat/query',[
], function () {
function Query (decorated, $element, options) {
if (console && console.warn) {
console.warn(
'Select2: The `query` option has been deprecated in favor of a ' +
'custom data adapter that overrides the `query` method. Support ' +
'will be removed for the `query` option in future versions of ' +
'Select2.'
);
}
decorated.call(this, $element, options);
}
Query.prototype.query = function (_, params, callback) {
params.callback = callback;
var query = this.options.get('query');
query.call(null, params);
};
return Query;
});
define('select2/dropdown/attachContainer',[
], function () {

View File

@ -3527,56 +3527,22 @@ define('select2/defaults',[
}
if (options.query != null) {
if (console && console.warn) {
console.warn(
'Select2: The `query` option has been deprecated in favor of a ' +
'custom data adapter that overrides the `query` method. Support ' +
'will be removed for the `query` option in future versions of ' +
'Select2.'
var Query = require(options.amdBase + 'compat/query');
options.dataAdapter = Utils.Decorate(
options.dataAdapter,
Query
);
}
options.dataAdapter.prototype.query = function (params, callback) {
params.callback = callback;
options.query.call(null, params);
};
}
if (options.initSelection != null) {
if (console && console.warn) {
console.warn(
'Select2: The `initSelection` option has been deprecated in favor' +
' of a custom data adapter that overrides the `current` method. ' +
'This method is now called multiple times instead of a single ' +
'time when the instance is initialized. Support will be removed ' +
'for the `initSelection` option in future versions of Select2'
var InitSelection = require(options.amdBase + 'compat/initSelection');
options.dataAdapter = Utils.Decorate(
options.dataAdapter,
InitSelection
);
}
var oldCurrent = options.dataAdapter.prototype.current;
var newCurrent = function (callback) {
var self = this;
if (this._isInitialized) {
oldCurrent.call(this, callback);
return;
}
options.initSelection.call(null, this.$element, function (data) {
self._isInitialized = true;
if (!$.isArray(data)) {
data = [data];
}
callback(data);
});
};
options.dataAdapter.prototype.current = newCurrent;
}
}
if (options.resultsAdapter == null) {

View File

@ -13062,56 +13062,22 @@ define('select2/defaults',[
}
if (options.query != null) {
if (console && console.warn) {
console.warn(
'Select2: The `query` option has been deprecated in favor of a ' +
'custom data adapter that overrides the `query` method. Support ' +
'will be removed for the `query` option in future versions of ' +
'Select2.'
var Query = require(options.amdBase + 'compat/query');
options.dataAdapter = Utils.Decorate(
options.dataAdapter,
Query
);
}
options.dataAdapter.prototype.query = function (params, callback) {
params.callback = callback;
options.query.call(null, params);
};
}
if (options.initSelection != null) {
if (console && console.warn) {
console.warn(
'Select2: The `initSelection` option has been deprecated in favor' +
' of a custom data adapter that overrides the `current` method. ' +
'This method is now called multiple times instead of a single ' +
'time when the instance is initialized. Support will be removed ' +
'for the `initSelection` option in future versions of Select2'
var InitSelection = require(options.amdBase + 'compat/initSelection');
options.dataAdapter = Utils.Decorate(
options.dataAdapter,
InitSelection
);
}
var oldCurrent = options.dataAdapter.prototype.current;
var newCurrent = function (callback) {
var self = this;
if (this._isInitialized) {
oldCurrent.call(this, callback);
return;
}
options.initSelection.call(null, this.$element, function (data) {
self._isInitialized = true;
if (!$.isArray(data)) {
data = [data];
}
callback(data);
});
};
options.dataAdapter.prototype.current = newCurrent;
}
}
if (options.resultsAdapter == null) {
@ -14198,6 +14164,76 @@ define('select2/compat/matcher',[
return oldMatcher;
});
define('select2/compat/initSelection',[
'jquery'
], function ($) {
function InitSelection (decorated, $element, options) {
if (console && console.warn) {
console.warn(
'Select2: The `initSelection` option has been deprecated in favor' +
' of a custom data adapter that overrides the `current` method. ' +
'This method is now called multiple times instead of a single ' +
'time when the instance is initialized. Support will be removed ' +
'for the `initSelection` option in future versions of Select2'
);
}
this.initSelection = options.get('initSelection');
this._isInitialized = false;
decorated.call(this, $element, options);
}
InitSelection.prototype.current = function (decorated, callback) {
var self = this;
if (this._isInitialized) {
decorated.call(this, callback);
return;
}
this.initSelection.call(null, this.$element, function (data) {
self._isInitialized = true;
if (!$.isArray(data)) {
data = [data];
}
callback(data);
});
};
return InitSelection;
});
define('select2/compat/query',[
], function () {
function Query (decorated, $element, options) {
if (console && console.warn) {
console.warn(
'Select2: The `query` option has been deprecated in favor of a ' +
'custom data adapter that overrides the `query` method. Support ' +
'will be removed for the `query` option in future versions of ' +
'Select2.'
);
}
decorated.call(this, $element, options);
}
Query.prototype.query = function (_, params, callback) {
params.callback = callback;
var query = this.options.get('query');
query.call(null, params);
};
return Query;
});
define('select2/dropdown/attachContainer',[
], function () {

File diff suppressed because one or more lines are too long

54
dist/js/select2.js vendored
View File

@ -3955,56 +3955,22 @@ define('select2/defaults',[
}
if (options.query != null) {
if (console && console.warn) {
console.warn(
'Select2: The `query` option has been deprecated in favor of a ' +
'custom data adapter that overrides the `query` method. Support ' +
'will be removed for the `query` option in future versions of ' +
'Select2.'
var Query = require(options.amdBase + 'compat/query');
options.dataAdapter = Utils.Decorate(
options.dataAdapter,
Query
);
}
options.dataAdapter.prototype.query = function (params, callback) {
params.callback = callback;
options.query.call(null, params);
};
}
if (options.initSelection != null) {
if (console && console.warn) {
console.warn(
'Select2: The `initSelection` option has been deprecated in favor' +
' of a custom data adapter that overrides the `current` method. ' +
'This method is now called multiple times instead of a single ' +
'time when the instance is initialized. Support will be removed ' +
'for the `initSelection` option in future versions of Select2'
var InitSelection = require(options.amdBase + 'compat/initSelection');
options.dataAdapter = Utils.Decorate(
options.dataAdapter,
InitSelection
);
}
var oldCurrent = options.dataAdapter.prototype.current;
var newCurrent = function (callback) {
var self = this;
if (this._isInitialized) {
oldCurrent.call(this, callback);
return;
}
options.initSelection.call(null, this.$element, function (data) {
self._isInitialized = true;
if (!$.isArray(data)) {
data = [data];
}
callback(data);
});
};
options.dataAdapter.prototype.current = newCurrent;
}
}
if (options.resultsAdapter == null) {

File diff suppressed because one or more lines are too long

View File

@ -133,6 +133,13 @@ slug: announcements-4.0
they are coming from older versions of Select2.
</p>
<p>
If you use the full build of Select2 (<code>select2.full.js</code>), you
will be automatically notified of the major breaking changes, and
compatibility modules will be used in some cases to ensure that your code
still behaves how you were expecting.
</p>
<h2 id="hidden-input">No more hidden input tags</h2>
<p>
@ -292,11 +299,23 @@ $("select").select2({
</h3>
<p>
In the past, whenever you wanted to use a custom data adapter, such as AJAX or tagging, you needed to help Select2 out in determining the initial values that were selected. This was typically done through the <code>initSelection</code> option, which took the underlying data of the input and converted it into data objects that Select2 could use.
In the past, whenever you wanted to use a custom data adapter, such as
AJAX or tagging, you needed to help Select2 out in determining the initial
values that were selected. This was typically done through the
<code>initSelection</code> option, which took the underlying data of the
input and converted it into data objects that Select2 could use.
</p>
<p>
This is now handled by <a href="options.html#dataAdapter">the data adapter</a> in the <code>current</code> method, which allows Select2 to convert the currently selected values into data objects that can be displayed. The default implementation converts the text and value of <code>option</code> elements into data objects, and is probably suitable for most cases. An example of the old <code>initSelection</code> option is included below, which converts the value of the selected options into a data object with both the <code>id</code> and <code>text</code> matching the selected value.
This is now handled by
<a href="options.html#dataAdapter">the data adapter</a> in the
<code>current</code> method, which allows Select2 to convert the currently
selected values into data objects that can be displayed. The default
implementation converts the text and value of <code>option</code> elements
into data objects, and is probably suitable for most cases. An example of
the old <code>initSelection</code> option is included below, which
converts the value of the selected options into a data object with both
the <code>id</code> and <code>text</code> matching the selected value.
</p>
<pre class="prettyprint linenums">
@ -310,7 +329,12 @@ initSelection : function (element, callback) {
</pre>
<p>
When using the new <code>current</code> method of the custom data adapter, <strong>this method is called any time Select2 needs a list</strong> of the currently selected options. This is different from the old <code>initSelection</code> in that it was only called once, so it could suffer from being relatively slow to process the data (such as from a remote data source).
When using the new <code>current</code> method of the custom data adapter,
<strong>this method is called any time Select2 needs a list</strong> of
the currently selected options. This is different from the old
<code>initSelection</code> in that it was only called once, so it could
suffer from being relatively slow to process the data (such as from a
remote data source).
</p>
<pre class="prettyprint linenums">
@ -348,7 +372,18 @@ function (ArrayData, Utils) {
</pre>
<p>
The new <code>current</code> method of the data adapter works in a similar way to the old <code>initSelection</code> method, with three notable differences. The first, and most important, is that <code>it is called whenever the current selections are needed</code> to ensure that Select2 is always displaying the most accurate and up to date data. No matter what type of element Select2 is attached to, whether it supports a single or multiple selections, the data passed to the callback <strong>must be an array, even if it contains one selection</strong>. The last is that there is only one parameter, the callback to be executed with the latest data, and the current element that Select2 is attached to is available on the class itself as <code>this.$element</code>.
The new <code>current</code> method of the data adapter works in a similar
way to the old <code>initSelection</code> method, with three notable
differences. The first, and most important, is that <code>it is called
whenever the current selections are needed</code> to ensure that Select2
is always displaying the most accurate and up to date data. No matter
what type of element Select2 is attached to, whether it supports a
single or multiple selections, the data passed to the callback
<strong>must be an array, even if it contains one selection</strong>.
The last is that there is only one parameter, the callback to be
executed with the latest data, and the current element that Select2 is
attached to is available on the class itself as
<code>this.$element</code>.
</p>
<h3 id="query-to-data-adapter">
@ -356,11 +391,24 @@ function (ArrayData, Utils) {
</h3>
<p>
<a href="http://select2.github.io/select2/#data">In the past</a>, any time you wanted to hook Select2 up to a diferent data source you would be required to implement custom <code>query</code> and <code>initSelection</code> methods. This allowed Select2 to determine the initial selection and the list of results to display, and it would handle everything else internally, which was fine more most people.
<a href="http://select2.github.io/select2/#data">In the past</a>, any time
you wanted to hook Select2 up to a diferent data source you would be
required to implement custom <code>query</code> and
<code>initSelection</code> methods. This allowed Select2 to determine the
initial selection and the list of results to display, and it would handle
everything else internally, which was fine more most people.
</p>
<p>
The custom <code>query</code> and <code>initSelection</code> methods have been replaced by <a href="options.html#dataAdapter">custom data adapters</a> that handle how Select2 stores and retrieves the data that will be displayed to the user. An example of the old <code>query</code> option is provided below, which is <a href="http://select2.github.io/select2/#data">the same as the old example</a>, and it generates results that contain the search term repeated a certain number of times.
The custom <code>query</code> and <code>initSelection</code> methods have
been replaced by
<a href="options.html#dataAdapter">custom data adapters</a> that handle
how Select2 stores and retrieves the data that will be displayed to the
user. An example of the old <code>query</code> option is provided below,
which is
<a href="http://select2.github.io/select2/#data">the same as the old example</a>,
and it generates results that contain the search term repeated a certain
number of times.
</p>
<pre class="prettyprint linenums">
@ -376,7 +424,9 @@ query: function (query) {
</pre>
<p>
This has been replaced by custom data adapters which define a similarly named <code>query</code> method. The comparable data adapter is provided below as an example.
This has been replaced by custom data adapters which define a similarly
named <code>query</code> method. The comparable data adapter is provided
below as an example.
</p>
<pre class="prettyprint linenums">
@ -417,7 +467,12 @@ function (ArrayData, Utils) {
</pre>
<p>
The new <code>query</code> method of the data adapter is very similar to the old <code>query</code> option that was passed into Select2 when initializing it. The old <code>query</code> argument is mostly the same as the new <code>params</code> that are passed in to query on, and the callback that should be used to return the results is now passed in as the second parameter.
The new <code>query</code> method of the data adapter is very similar to
the old <code>query</code> option that was passed into Select2 when
initializing it. The old <code>query</code> argument is mostly the same as
the new <code>params</code> that are passed in to query on, and the
callback that should be used to return the results is now passed in as the
second parameter.
</p>
<h3 id="changed-templating">Renamed templating options</h3>
@ -445,9 +500,9 @@ function (ArrayData, Utils) {
<p>
When working with array and AJAX data in the past, Select2 allowed a
custom <code>id</code> function or attribute to be set in various places,
ranging from the initialization of Select2 to when the remote data was being
returned. This allowed Select2 to better integrate with existing data
sources that did not necessarily use the <code>id</code> attribute to
ranging from the initialization of Select2 to when the remote data was
being returned. This allowed Select2 to better integrate with existing
data sources that did not necessarily use the <code>id</code> attribute to
indicate the unique identifier for an object.
</p>

View File

@ -942,6 +942,122 @@ DataAdapter.query = function (params, callback) {
</dd>
</dl>
</section>
<section id="compatibility">
<div class="page-header">
<h1>Backwards compatibility</h1>
</div>
<p>
Select2 offers limited backwards compatibility with the previously 3.5.x
release line, allowing people more efficiently transfer across releases
and get the latest features. For many of the larger changes, such as the
change in how custom data adapters work, compatibility modules were
created that will be used to assist in the upgrade process. It is not
recommended to rely on these compatibility modules, as they will not
always exist, but they make upgrading easier for major changes.
</p>
<p>
<strong>The compatibility modules are only included in the full builds of
Select2</strong>. These files end in <code>.full.js</code>, and the
compatibility modules are prefixed with <code>select2/compat</code>.
</p>
<h2 id="initSelection">
Old initial selections with <code>initSelection</code>
</h2>
<p class="alert alert-warning">
<a href="announcements-4.0.html#removed-initselection" class="alert-link">Deprecated in Select2 4.0.</a>
This has been replaced by another option.
</p>
<p>
In the past, Select2 required an option called <code>initSelection</code>
that was defined whenever a custom data source was being used, allowing
for the initial selection for the component to be determined. This has
been replaced by the <code>current</code> method on the
<a href="#dataAdapter">data adapter</a>.
</p>
<div class="row">
<div class="col-sm-6">
<dl class="dl-horizontal">
<dt>Key</dt>
<dd>
<code>initSelection</code>
</dd>
<dt>Value</dt>
<dd>
A function taking a <code>callback</code>
</dd>
</dl>
</div>
<div class="col-sm-6">
<dl class="dl-horizontal">
<dt>Adapter</dt>
<dd>
<code title="select2/data/base">DataAdapter</code>
</dd>
<dt>Decorator</dt>
<dd>
<code title="select2/compat/initSelection">InitSelection</code>
</dd>
</dl>
</div>
</div>
<h2 id="query">
Querying old data with <code>query</code>
</h2>
<p class="alert alert-warning">
<a href="announcements-4.0.html#query-to-data-adapter" class="alert-link">Deprecated in Select2 4.0.</a>
This has been replaced by another option.
</p>
<p>
In the past, Select2 supported an option called <code>query</code> that
allowed for a custom data source to be used. This option has been replaced
by the <code>query</code> method on the
<a href="#dataAdapter">data adapter</a> and takes a very similar set of
parameters.
</p>
<div class="row">
<div class="col-sm-6">
<dl class="dl-horizontal">
<dt>Key</dt>
<dd>
<code>query</code>
</dd>
<dt>Value</dt>
<dd>
A function taking <code>params</code> (including a <code>callback</code>)
</dd>
</dl>
</div>
<div class="col-sm-6">
<dl class="dl-horizontal">
<dt>Adapter</dt>
<dd>
<code title="select2/data/base">DataAdapter</code>
</dd>
<dt>Decorator</dt>
<dd>
<code title="select2/compat/query">Query</code>
</dd>
</dl>
</div>
</div>
</section>
</div>
<script type="text/javascript">

42
src/js/select2/compat/initSelection.js vendored Normal file
View File

@ -0,0 +1,42 @@
define([
'jquery'
], function ($) {
function InitSelection (decorated, $element, options) {
if (console && console.warn) {
console.warn(
'Select2: The `initSelection` option has been deprecated in favor' +
' of a custom data adapter that overrides the `current` method. ' +
'This method is now called multiple times instead of a single ' +
'time when the instance is initialized. Support will be removed ' +
'for the `initSelection` option in future versions of Select2'
);
}
this.initSelection = options.get('initSelection');
this._isInitialized = false;
decorated.call(this, $element, options);
}
InitSelection.prototype.current = function (decorated, callback) {
var self = this;
if (this._isInitialized) {
decorated.call(this, callback);
return;
}
this.initSelection.call(null, this.$element, function (data) {
self._isInitialized = true;
if (!$.isArray(data)) {
data = [data];
}
callback(data);
});
};
return InitSelection;
});

26
src/js/select2/compat/query.js vendored Normal file
View File

@ -0,0 +1,26 @@
define([
], function () {
function Query (decorated, $element, options) {
if (console && console.warn) {
console.warn(
'Select2: The `query` option has been deprecated in favor of a ' +
'custom data adapter that overrides the `query` method. Support ' +
'will be removed for the `query` option in future versions of ' +
'Select2.'
);
}
decorated.call(this, $element, options);
}
Query.prototype.query = function (_, params, callback) {
params.callback = callback;
var query = this.options.get('query');
query.call(null, params);
};
return Query;
});

View File

@ -94,56 +94,22 @@ define([
}
if (options.query != null) {
if (console && console.warn) {
console.warn(
'Select2: The `query` option has been deprecated in favor of a ' +
'custom data adapter that overrides the `query` method. Support ' +
'will be removed for the `query` option in future versions of ' +
'Select2.'
var Query = require(options.amdBase + 'compat/query');
options.dataAdapter = Utils.Decorate(
options.dataAdapter,
Query
);
}
options.dataAdapter.prototype.query = function (params, callback) {
params.callback = callback;
options.query.call(null, params);
};
}
if (options.initSelection != null) {
if (console && console.warn) {
console.warn(
'Select2: The `initSelection` option has been deprecated in favor' +
' of a custom data adapter that overrides the `current` method. ' +
'This method is now called multiple times instead of a single ' +
'time when the instance is initialized. Support will be removed ' +
'for the `initSelection` option in future versions of Select2'
var InitSelection = require(options.amdBase + 'compat/initSelection');
options.dataAdapter = Utils.Decorate(
options.dataAdapter,
InitSelection
);
}
var oldCurrent = options.dataAdapter.prototype.current;
var newCurrent = function (callback) {
var self = this;
if (this._isInitialized) {
oldCurrent.call(this, callback);
return;
}
options.initSelection.call(null, this.$element, function (data) {
self._isInitialized = true;
if (!$.isArray(data)) {
data = [data];
}
callback(data);
});
};
options.dataAdapter.prototype.current = newCurrent;
}
}
if (options.resultsAdapter == null) {

View File

@ -11,7 +11,7 @@
<script src="../vendor/qunit-1.14.0.js" type="text/javascript"></script>
<script src="../../vendor/almond-0.2.9.js" type="text/javascript"></script>
<script src="../../vendor/jquery-2.1.0.js" type="text/javascript"></script>
<script src="../../dist/js/select2.amd.js" type="text/javascript"></script>
<script src="../../dist/js/select2.amd.full.js" type="text/javascript"></script>
<script src="deprecated-tests.js" type="text/javascript"></script>
</body>